blob: 9be71678690133ec2baa0672cdfbeac7b0b31b1d [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
minyue@webrtc.org74aaf292014-07-16 21:28:26 +000017#include "webrtc/base/exp_filter.h"
pbosba8c15b2015-07-14 09:36:34 -070018#include "webrtc/base/scoped_ptr.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010019#include "webrtc/modules/video_coding/internal_defines.h"
20#include "webrtc/modules/video_coding/qm_select.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010021#include "webrtc/system_wrappers/include/trace.h"
stefan@webrtc.orgeb917922013-02-18 14:40:18 +000022#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000023
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000024namespace webrtc {
25namespace media_optimization {
26
marpan@google.com30ecda12011-09-09 17:15:12 +000027// Number of time periods used for (max) window filter for packet loss
28// TODO (marpan): set reasonable window size for filtered packet loss,
29// adjustment should be based on logged/real data of loss stats/correlation.
30enum { kLossPrHistorySize = 10 };
31
32// 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
mikhal@google.comb29d9402011-08-01 16:39:20 +000033enum { kLossPrShortFilterWinMs = 1000 };
niklase@google.com470e71d2011-07-07 08:21:25 +000034
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +000035// The type of filter used on the received packet loss reports.
36enum FilterPacketLossMode {
37 kNoFilter, // No filtering on received loss.
38 kAvgFilter, // Recursive average filter.
39 kMaxFilter // Max-window filter, over the time interval of:
40 // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
41};
42
niklase@google.com470e71d2011-07-07 08:21:25 +000043// Thresholds for hybrid NACK/FEC
44// common to media optimization and the jitter buffer.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000045const int64_t kLowRttNackMs = 20;
niklase@google.com470e71d2011-07-07 08:21:25 +000046
47struct VCMProtectionParameters
48{
mikhal@webrtc.orga057a952011-08-26 21:17:34 +000049 VCMProtectionParameters() : rtt(0), lossPr(0.0f), bitRate(0.0f),
50 packetsPerFrame(0.0f), packetsPerFrameKey(0.0f), frameRate(0.0f),
51 keyFrameSize(0.0f), fecRateDelta(0), fecRateKey(0),
Peter Boström9cb1f302015-04-01 11:39:49 +020052 codecWidth(0), codecHeight(0),
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +000053 numLayers(1)
mikhal@google.comb29d9402011-08-01 16:39:20 +000054 {}
niklase@google.com470e71d2011-07-07 08:21:25 +000055
pkasting@chromium.org16825b12015-01-12 21:51:21 +000056 int64_t rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +000057 float lossPr;
58 float bitRate;
59 float packetsPerFrame;
60 float packetsPerFrameKey;
61 float frameRate;
62 float keyFrameSize;
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +000063 uint8_t fecRateDelta;
64 uint8_t fecRateKey;
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +000065 uint16_t codecWidth;
66 uint16_t codecHeight;
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +000067 int numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +000068};
69
70
71/******************************/
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000072/* VCMProtectionMethod class */
73/******************************/
niklase@google.com470e71d2011-07-07 08:21:25 +000074
75enum VCMProtectionMethodEnum
76{
mikhal@webrtc.orga057a952011-08-26 21:17:34 +000077 kNack,
78 kFec,
niklase@google.com470e71d2011-07-07 08:21:25 +000079 kNackFec,
niklase@google.com470e71d2011-07-07 08:21:25 +000080 kNone
81};
82
83class VCMLossProbabilitySample
84{
85public:
86 VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {};
87
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +000088 uint8_t lossPr255;
89 int64_t timeMs;
niklase@google.com470e71d2011-07-07 08:21:25 +000090};
91
92
niklase@google.com470e71d2011-07-07 08:21:25 +000093class VCMProtectionMethod
94{
95public:
mikhal@webrtc.orga057a952011-08-26 21:17:34 +000096 VCMProtectionMethod();
97 virtual ~VCMProtectionMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +000098
99 // Updates the efficiency of the method using the parameters provided
100 //
101 // Input:
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000102 // - parameters : Parameters used to calculate efficiency
niklase@google.com470e71d2011-07-07 08:21:25 +0000103 //
104 // Return value : True if this method is recommended in
105 // the given conditions.
106 virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
107
108 // Returns the protection type
109 //
110 // Return value : The protection type
111 enum VCMProtectionMethodEnum Type() const { return _type; }
112
niklase@google.com470e71d2011-07-07 08:21:25 +0000113 // Returns the effective packet loss for ER, required by this protection method
114 //
115 // Return value : Required effective packet loss
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000116 virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
118 // Extracts the FEC protection factor for Key frame, required by this protection method
119 //
120 // Return value : Required protectionFactor for Key frame
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000121 virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000122
123 // Extracts the FEC protection factor for Delta frame, required by this protection method
124 //
125 // Return value : Required protectionFactor for delta frame
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000126 virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000127
marpan@google.com59fd0f12011-07-13 17:19:49 +0000128 // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
129 //
130 // Return value : Required Unequal protection on/off state.
mikhal@webrtc.org685383d2011-08-17 23:19:54 +0000131 virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }
marpan@google.com59fd0f12011-07-13 17:19:49 +0000132
133 // Extracts whether the the FEC Unequal protection (UEP) is used for Delta frame.
134 //
135 // Return value : Required Unequal protection on/off state.
mikhal@webrtc.org685383d2011-08-17 23:19:54 +0000136 virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }
marpan@google.com59fd0f12011-07-13 17:19:49 +0000137
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000138 virtual int MaxFramesFec() const { return 1; }
139
marpan@google.com86548c62011-07-12 17:12:57 +0000140 // Updates content metrics
mikhal@google.comb29d9402011-08-01 16:39:20 +0000141 void UpdateContentMetrics(const VideoContentMetrics* contentMetrics);
marpan@google.com86548c62011-07-12 17:12:57 +0000142
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000143protected:
144
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000145 uint8_t _effectivePacketLoss;
146 uint8_t _protectionFactorK;
147 uint8_t _protectionFactorD;
mikhal@google.com022716b2011-07-20 23:12:57 +0000148 // Estimation of residual loss after the FEC
niklase@google.com470e71d2011-07-07 08:21:25 +0000149 float _scaleProtKey;
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000150 int32_t _maxPayloadSize;
niklase@google.com470e71d2011-07-07 08:21:25 +0000151
marpan@google.com86548c62011-07-12 17:12:57 +0000152 VCMQmRobustness* _qmRobustness;
marpan@google.com59fd0f12011-07-13 17:19:49 +0000153 bool _useUepProtectionK;
154 bool _useUepProtectionD;
marpan@google.com191b7802011-08-01 19:59:57 +0000155 float _corrFecCost;
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000156 enum VCMProtectionMethodEnum _type;
niklase@google.com470e71d2011-07-07 08:21:25 +0000157};
158
159class VCMNackMethod : public VCMProtectionMethod
160{
161public:
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000162 VCMNackMethod();
163 virtual ~VCMNackMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000164 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
mikhal@google.comb29d9402011-08-01 16:39:20 +0000165 // Get the effective packet loss
166 bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000167};
168
169class VCMFecMethod : public VCMProtectionMethod
170{
171public:
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000172 VCMFecMethod();
173 virtual ~VCMFecMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000174 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
mikhal@google.com022716b2011-07-20 23:12:57 +0000175 // Get the effective packet loss for ER
niklase@google.com470e71d2011-07-07 08:21:25 +0000176 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
mikhal@google.com022716b2011-07-20 23:12:57 +0000177 // Get the FEC protection factors
niklase@google.com470e71d2011-07-07 08:21:25 +0000178 bool ProtectionFactor(const VCMProtectionParameters* parameters);
mikhal@google.com022716b2011-07-20 23:12:57 +0000179 // Get the boost for key frame protection
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000180 uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
181 uint8_t packetFrameKey) const;
mikhal@google.com022716b2011-07-20 23:12:57 +0000182 // Convert the rates: defined relative to total# packets or source# packets
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000183 uint8_t ConvertFECRate(uint8_t codeRate) const;
mikhal@google.com022716b2011-07-20 23:12:57 +0000184 // Get the average effective recovery from FEC: for random loss model
niklase@google.com470e71d2011-07-07 08:21:25 +0000185 float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
mikhal@google.com679450f2011-08-01 22:14:58 +0000186 // Update FEC with protectionFactorD
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000187 void UpdateProtectionFactorD(uint8_t protectionFactorD);
mikhal@webrtc.orgd0752c32011-10-19 15:48:30 +0000188 // Update FEC with protectionFactorK
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000189 void UpdateProtectionFactorK(uint8_t protectionFactorK);
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +0000190 // Compute the bits per frame. Account for temporal layers when applicable.
191 int BitsPerFrame(const VCMProtectionParameters* parameters);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000192
193protected:
194 enum { kUpperLimitFramesFec = 6 };
marpan@webrtc.org88ad06b2012-04-20 16:05:24 +0000195 // Thresholds values for the bytes/frame and round trip time, below which we
196 // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
197 // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
198 enum { kMaxBytesPerFrameForFec = 700 };
199 // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
200 enum { kMaxBytesPerFrameForFecLow = 400 };
201 // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
202 enum { kMaxBytesPerFrameForFecHigh = 1000 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000203};
204
205
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000206class VCMNackFecMethod : public VCMFecMethod
niklase@google.com470e71d2011-07-07 08:21:25 +0000207{
208public:
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000209 VCMNackFecMethod(int64_t lowRttNackThresholdMs,
210 int64_t highRttNackThresholdMs);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000211 virtual ~VCMNackFecMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
mikhal@google.com022716b2011-07-20 23:12:57 +0000213 // Get the effective packet loss for ER
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000215 // Get the protection factors
niklase@google.com470e71d2011-07-07 08:21:25 +0000216 bool ProtectionFactor(const VCMProtectionParameters* parameters);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000217 // Get the max number of frames the FEC is allowed to be based on.
218 int MaxFramesFec() const;
marpan@webrtc.org88ad06b2012-04-20 16:05:24 +0000219 // Turn off the FEC based on low bitrate and other factors.
220 bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
stefan@webrtc.org932ab182011-11-29 11:33:31 +0000221private:
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000222 int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
223
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000224 int64_t _lowRttNackMs;
225 int64_t _highRttNackMs;
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000226 int _maxFramesFec;
niklase@google.com470e71d2011-07-07 08:21:25 +0000227};
228
229class VCMLossProtectionLogic
230{
231public:
henrik.lundin@webrtc.org7d8c72e2011-12-21 15:24:01 +0000232 VCMLossProtectionLogic(int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000233 ~VCMLossProtectionLogic();
234
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000235 // Set the protection method to be used
236 //
237 // Input:
238 // - newMethodType : New requested protection method type. If one
239 // is already set, it will be deleted and replaced
pbos@webrtc.orgcade82c2015-03-12 10:39:24 +0000240 void SetMethod(VCMProtectionMethodEnum newMethodType);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000241
niklase@google.com470e71d2011-07-07 08:21:25 +0000242 // Update the round-trip time
243 //
244 // Input:
245 // - rtt : Round-trip time in seconds.
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000246 void UpdateRtt(int64_t rtt);
niklase@google.com470e71d2011-07-07 08:21:25 +0000247
niklase@google.com470e71d2011-07-07 08:21:25 +0000248 // Update the filtered packet loss.
249 //
250 // Input:
mikhal@google.com022716b2011-07-20 23:12:57 +0000251 // - packetLossEnc : The reported packet loss filtered
252 // (max window or average)
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000253 void UpdateFilteredLossPr(uint8_t packetLossEnc);
niklase@google.com470e71d2011-07-07 08:21:25 +0000254
255 // Update the current target bit rate.
256 //
257 // Input:
258 // - bitRate : The current target bit rate in kbits/s
259 void UpdateBitRate(float bitRate);
260
261 // Update the number of packets per frame estimate, for delta frames
262 //
263 // Input:
mikhal@google.com022716b2011-07-20 23:12:57 +0000264 // - nPackets : Number of packets in the latest sent frame.
henrik.lundin@webrtc.org7d8c72e2011-12-21 15:24:01 +0000265 void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000266
267 // Update the number of packets per frame estimate, for key frames
268 //
269 // Input:
mikhal@google.com022716b2011-07-20 23:12:57 +0000270 // - nPackets : umber of packets in the latest sent frame.
henrik.lundin@webrtc.org7d8c72e2011-12-21 15:24:01 +0000271 void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000272
273 // Update the keyFrameSize estimate
274 //
275 // Input:
276 // - keyFrameSize : The size of the latest sent key frame.
277 void UpdateKeyFrameSize(float keyFrameSize);
278
279 // Update the frame rate
280 //
281 // Input:
282 // - frameRate : The current target frame rate.
283 void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
284
285 // Update the frame size
286 //
287 // Input:
288 // - width : The codec frame width.
289 // - height : The codec frame height.
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000290 void UpdateFrameSize(uint16_t width, uint16_t height);
niklase@google.com470e71d2011-07-07 08:21:25 +0000291
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +0000292 // Update the number of active layers
293 //
294 // Input:
295 // - numLayers : Number of layers used.
296 void UpdateNumLayers(int numLayers);
297
niklase@google.com470e71d2011-07-07 08:21:25 +0000298 // The amount of packet loss to cover for with FEC.
299 //
300 // Input:
mikhal@google.comb29d9402011-08-01 16:39:20 +0000301 // - fecRateKey : Packet loss to cover for with FEC when
302 // sending key frames.
303 // - fecRateDelta : Packet loss to cover for with FEC when
304 // sending delta frames.
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000305 void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta)
mikhal@google.comb29d9402011-08-01 16:39:20 +0000306 { _fecRateKey = fecRateKey;
307 _fecRateDelta = fecRateDelta; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000308
mikhal@google.comb29d9402011-08-01 16:39:20 +0000309 // Update the protection methods with the current VCMProtectionParameters
mikhal@webrtc.org06ad81f2011-08-23 16:03:59 +0000310 // and set the requested protection settings.
mikhal@google.comb29d9402011-08-01 16:39:20 +0000311 // Return value : Returns true on update
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000312 bool UpdateMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000313
314 // Returns the method currently selected.
315 //
316 // Return value : The protection method currently selected.
317 VCMProtectionMethod* SelectedMethod() const;
318
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000319 // Return the protection type of the currently selected method
320 VCMProtectionMethodEnum SelectedType() const;
321
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +0000322 // Updates the filtered loss for the average and max window packet loss,
323 // and returns the filtered loss probability in the interval [0, 255].
324 // The returned filtered loss value depends on the parameter |filter_mode|.
325 // The input parameter |lossPr255| is the received packet loss.
326
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 // Return value : The filtered loss probability
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000328 uint8_t FilteredLoss(int64_t nowMs, FilterPacketLossMode filter_mode,
329 uint8_t lossPr255);
niklase@google.com470e71d2011-07-07 08:21:25 +0000330
henrik.lundin@webrtc.org7d8c72e2011-12-21 15:24:01 +0000331 void Reset(int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000332
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000333 void Release();
334
niklase@google.com470e71d2011-07-07 08:21:25 +0000335private:
336 // Sets the available loss protection methods.
pbos@webrtc.org7b859cc2013-04-02 15:54:38 +0000337 void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
338 uint8_t MaxFilteredLossPr(int64_t nowMs) const;
pbosba8c15b2015-07-14 09:36:34 -0700339 rtc::scoped_ptr<VCMProtectionMethod> _selectedMethod;
minyue@webrtc.org74aaf292014-07-16 21:28:26 +0000340 VCMProtectionParameters _currentParameters;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000341 int64_t _rtt;
minyue@webrtc.org74aaf292014-07-16 21:28:26 +0000342 float _lossPr;
343 float _bitRate;
344 float _frameRate;
345 float _keyFrameSize;
346 uint8_t _fecRateKey;
347 uint8_t _fecRateDelta;
348 int64_t _lastPrUpdateT;
349 int64_t _lastPacketPerFrameUpdateT;
350 int64_t _lastPacketPerFrameUpdateTKey;
351 rtc::ExpFilter _lossPr255;
352 VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
353 uint8_t _shortMaxLossPr255;
354 rtc::ExpFilter _packetsPerFrame;
355 rtc::ExpFilter _packetsPerFrameKey;
minyue@webrtc.org74aaf292014-07-16 21:28:26 +0000356 uint16_t _codecWidth;
357 uint16_t _codecHeight;
358 int _numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +0000359};
360
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000361} // namespace media_optimization
362} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000363
364#endif // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_