media_opt_util.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. #ifndef MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
  11. #define MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
  12. #include <math.h>
  13. #include <stdlib.h>
  14. #include <memory>
  15. #include "modules/video_coding/internal_defines.h"
  16. #include "rtc_base/experiments/rate_control_settings.h"
  17. #include "rtc_base/numerics/exp_filter.h"
  18. namespace webrtc {
  19. namespace media_optimization {
  20. // Number of time periods used for (max) window filter for packet loss
  21. // TODO(marpan): set reasonable window size for filtered packet loss,
  22. // adjustment should be based on logged/real data of loss stats/correlation.
  23. enum { kLossPrHistorySize = 10 };
  24. // 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
  25. enum { kLossPrShortFilterWinMs = 1000 };
  26. // The type of filter used on the received packet loss reports.
  27. enum FilterPacketLossMode {
  28. kNoFilter, // No filtering on received loss.
  29. kAvgFilter, // Recursive average filter.
  30. kMaxFilter // Max-window filter, over the time interval of:
  31. // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
  32. };
  33. // Thresholds for hybrid NACK/FEC
  34. // common to media optimization and the jitter buffer.
  35. const int64_t kLowRttNackMs = 20;
  36. // If the RTT is higher than this an extra RTT wont be added to to the jitter
  37. // buffer delay.
  38. const int kMaxRttDelayThreshold = 500;
  39. struct VCMProtectionParameters {
  40. VCMProtectionParameters();
  41. int64_t rtt;
  42. float lossPr;
  43. float bitRate;
  44. float packetsPerFrame;
  45. float packetsPerFrameKey;
  46. float frameRate;
  47. float keyFrameSize;
  48. uint8_t fecRateDelta;
  49. uint8_t fecRateKey;
  50. uint16_t codecWidth;
  51. uint16_t codecHeight;
  52. int numLayers;
  53. };
  54. /******************************/
  55. /* VCMProtectionMethod class */
  56. /******************************/
  57. enum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone };
  58. class VCMLossProbabilitySample {
  59. public:
  60. VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {}
  61. uint8_t lossPr255;
  62. int64_t timeMs;
  63. };
  64. class VCMProtectionMethod {
  65. public:
  66. VCMProtectionMethod();
  67. virtual ~VCMProtectionMethod();
  68. // Updates the efficiency of the method using the parameters provided
  69. //
  70. // Input:
  71. // - parameters : Parameters used to calculate efficiency
  72. //
  73. // Return value : True if this method is recommended in
  74. // the given conditions.
  75. virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
  76. // Returns the protection type
  77. //
  78. // Return value : The protection type
  79. VCMProtectionMethodEnum Type() const;
  80. // Returns the effective packet loss for ER, required by this protection
  81. // method
  82. //
  83. // Return value : Required effective packet loss
  84. virtual uint8_t RequiredPacketLossER();
  85. // Extracts the FEC protection factor for Key frame, required by this
  86. // protection method
  87. //
  88. // Return value : Required protectionFactor for Key frame
  89. virtual uint8_t RequiredProtectionFactorK();
  90. // Extracts the FEC protection factor for Delta frame, required by this
  91. // protection method
  92. //
  93. // Return value : Required protectionFactor for delta frame
  94. virtual uint8_t RequiredProtectionFactorD();
  95. // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
  96. //
  97. // Return value : Required Unequal protection on/off state.
  98. virtual bool RequiredUepProtectionK();
  99. // Extracts whether the the FEC Unequal protection (UEP) is used for Delta
  100. // frame.
  101. //
  102. // Return value : Required Unequal protection on/off state.
  103. virtual bool RequiredUepProtectionD();
  104. virtual int MaxFramesFec() const;
  105. protected:
  106. uint8_t _effectivePacketLoss;
  107. uint8_t _protectionFactorK;
  108. uint8_t _protectionFactorD;
  109. // Estimation of residual loss after the FEC
  110. float _scaleProtKey;
  111. int32_t _maxPayloadSize;
  112. bool _useUepProtectionK;
  113. bool _useUepProtectionD;
  114. float _corrFecCost;
  115. VCMProtectionMethodEnum _type;
  116. };
  117. class VCMNackMethod : public VCMProtectionMethod {
  118. public:
  119. VCMNackMethod();
  120. ~VCMNackMethod() override;
  121. bool UpdateParameters(const VCMProtectionParameters* parameters) override;
  122. // Get the effective packet loss
  123. bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
  124. };
  125. class VCMFecMethod : public VCMProtectionMethod {
  126. public:
  127. VCMFecMethod();
  128. ~VCMFecMethod() override;
  129. bool UpdateParameters(const VCMProtectionParameters* parameters) override;
  130. // Get the effective packet loss for ER
  131. bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
  132. // Get the FEC protection factors
  133. bool ProtectionFactor(const VCMProtectionParameters* parameters);
  134. // Get the boost for key frame protection
  135. uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
  136. uint8_t packetFrameKey) const;
  137. // Convert the rates: defined relative to total# packets or source# packets
  138. uint8_t ConvertFECRate(uint8_t codeRate) const;
  139. // Get the average effective recovery from FEC: for random loss model
  140. float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
  141. // Update FEC with protectionFactorD
  142. void UpdateProtectionFactorD(uint8_t protectionFactorD);
  143. // Update FEC with protectionFactorK
  144. void UpdateProtectionFactorK(uint8_t protectionFactorK);
  145. // Compute the bits per frame. Account for temporal layers when applicable.
  146. int BitsPerFrame(const VCMProtectionParameters* parameters);
  147. protected:
  148. enum { kUpperLimitFramesFec = 6 };
  149. // Thresholds values for the bytes/frame and round trip time, below which we
  150. // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
  151. // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
  152. enum { kMaxBytesPerFrameForFec = 700 };
  153. // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
  154. enum { kMaxBytesPerFrameForFecLow = 400 };
  155. // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
  156. enum { kMaxBytesPerFrameForFecHigh = 1000 };
  157. const RateControlSettings rate_control_settings_;
  158. };
  159. class VCMNackFecMethod : public VCMFecMethod {
  160. public:
  161. VCMNackFecMethod(int64_t lowRttNackThresholdMs,
  162. int64_t highRttNackThresholdMs);
  163. ~VCMNackFecMethod() override;
  164. bool UpdateParameters(const VCMProtectionParameters* parameters) override;
  165. // Get the effective packet loss for ER
  166. bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
  167. // Get the protection factors
  168. bool ProtectionFactor(const VCMProtectionParameters* parameters);
  169. // Get the max number of frames the FEC is allowed to be based on.
  170. int MaxFramesFec() const override;
  171. // Turn off the FEC based on low bitrate and other factors.
  172. bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
  173. private:
  174. int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
  175. int64_t _lowRttNackMs;
  176. int64_t _highRttNackMs;
  177. int _maxFramesFec;
  178. };
  179. class VCMLossProtectionLogic {
  180. public:
  181. explicit VCMLossProtectionLogic(int64_t nowMs);
  182. ~VCMLossProtectionLogic();
  183. // Set the protection method to be used
  184. //
  185. // Input:
  186. // - newMethodType : New requested protection method type. If one
  187. // is already set, it will be deleted and replaced
  188. void SetMethod(VCMProtectionMethodEnum newMethodType);
  189. // Update the round-trip time
  190. //
  191. // Input:
  192. // - rtt : Round-trip time in seconds.
  193. void UpdateRtt(int64_t rtt);
  194. // Update the filtered packet loss.
  195. //
  196. // Input:
  197. // - packetLossEnc : The reported packet loss filtered
  198. // (max window or average)
  199. void UpdateFilteredLossPr(uint8_t packetLossEnc);
  200. // Update the current target bit rate.
  201. //
  202. // Input:
  203. // - bitRate : The current target bit rate in kbits/s
  204. void UpdateBitRate(float bitRate);
  205. // Update the number of packets per frame estimate, for delta frames
  206. //
  207. // Input:
  208. // - nPackets : Number of packets in the latest sent frame.
  209. void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
  210. // Update the number of packets per frame estimate, for key frames
  211. //
  212. // Input:
  213. // - nPackets : umber of packets in the latest sent frame.
  214. void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
  215. // Update the keyFrameSize estimate
  216. //
  217. // Input:
  218. // - keyFrameSize : The size of the latest sent key frame.
  219. void UpdateKeyFrameSize(float keyFrameSize);
  220. // Update the frame rate
  221. //
  222. // Input:
  223. // - frameRate : The current target frame rate.
  224. void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
  225. // Update the frame size
  226. //
  227. // Input:
  228. // - width : The codec frame width.
  229. // - height : The codec frame height.
  230. void UpdateFrameSize(size_t width, size_t height);
  231. // Update the number of active layers
  232. //
  233. // Input:
  234. // - numLayers : Number of layers used.
  235. void UpdateNumLayers(int numLayers);
  236. // The amount of packet loss to cover for with FEC.
  237. //
  238. // Input:
  239. // - fecRateKey : Packet loss to cover for with FEC when
  240. // sending key frames.
  241. // - fecRateDelta : Packet loss to cover for with FEC when
  242. // sending delta frames.
  243. void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) {
  244. _fecRateKey = fecRateKey;
  245. _fecRateDelta = fecRateDelta;
  246. }
  247. // Update the protection methods with the current VCMProtectionParameters
  248. // and set the requested protection settings.
  249. // Return value : Returns true on update
  250. bool UpdateMethod();
  251. // Returns the method currently selected.
  252. //
  253. // Return value : The protection method currently selected.
  254. VCMProtectionMethod* SelectedMethod() const;
  255. // Return the protection type of the currently selected method
  256. VCMProtectionMethodEnum SelectedType() const;
  257. // Updates the filtered loss for the average and max window packet loss,
  258. // and returns the filtered loss probability in the interval [0, 255].
  259. // The returned filtered loss value depends on the parameter |filter_mode|.
  260. // The input parameter |lossPr255| is the received packet loss.
  261. // Return value : The filtered loss probability
  262. uint8_t FilteredLoss(int64_t nowMs,
  263. FilterPacketLossMode filter_mode,
  264. uint8_t lossPr255);
  265. void Reset(int64_t nowMs);
  266. void Release();
  267. private:
  268. // Sets the available loss protection methods.
  269. void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
  270. uint8_t MaxFilteredLossPr(int64_t nowMs) const;
  271. std::unique_ptr<VCMProtectionMethod> _selectedMethod;
  272. VCMProtectionParameters _currentParameters;
  273. int64_t _rtt;
  274. float _lossPr;
  275. float _bitRate;
  276. float _frameRate;
  277. float _keyFrameSize;
  278. uint8_t _fecRateKey;
  279. uint8_t _fecRateDelta;
  280. int64_t _lastPrUpdateT;
  281. int64_t _lastPacketPerFrameUpdateT;
  282. int64_t _lastPacketPerFrameUpdateTKey;
  283. rtc::ExpFilter _lossPr255;
  284. VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
  285. uint8_t _shortMaxLossPr255;
  286. rtc::ExpFilter _packetsPerFrame;
  287. rtc::ExpFilter _packetsPerFrameKey;
  288. size_t _codecWidth;
  289. size_t _codecHeight;
  290. int _numLayers;
  291. };
  292. } // namespace media_optimization
  293. } // namespace webrtc
  294. #endif // MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_