1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
28fe03af6743cacb9f9303b1bbe878a9e4f34739fstefan@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1412dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <math.h>
1512dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <stdlib.h>
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1774aaf29a0ff1b211dbfdbb6309791111a7871779minyue@webrtc.org#include "webrtc/base/exp_filter.h"
18ba8c15b857c0f341d9c1e02d41b6ccd56f9f1030pbos#include "webrtc/base/scoped_ptr.h"
192557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/internal_defines.h"
202557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/qm_select.h"
2198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h"
22eb91792cfd98a76192a855365bb785c0f581b94bstefan@webrtc.org#include "webrtc/typedefs.h"
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
24a64300af5043576c3191ba054dd4040f371af737stefan@webrtc.orgnamespace webrtc {
25a64300af5043576c3191ba054dd4040f371af737stefan@webrtc.orgnamespace media_optimization {
26a64300af5043576c3191ba054dd4040f371af737stefan@webrtc.org
2730ecda146a7e456d7894fa09d7d558d1600e3386marpan@google.com// Number of time periods used for (max) window filter for packet loss
289d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel// TODO(marpan): set reasonable window size for filtered packet loss,
2930ecda146a7e456d7894fa09d7d558d1600e3386marpan@google.com// adjustment should be based on logged/real data of loss stats/correlation.
3030ecda146a7e456d7894fa09d7d558d1600e3386marpan@google.comenum { kLossPrHistorySize = 10 };
3130ecda146a7e456d7894fa09d7d558d1600e3386marpan@google.com
3230ecda146a7e456d7894fa09d7d558d1600e3386marpan@google.com// 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
33b29d940db7c61cc12e9464c6b6838fe1b27581b3mikhal@google.comenum { kLossPrShortFilterWinMs = 1000 };
34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
352dad3fbe492dceacbfc55b2e2e0648be37624b1emarpan@webrtc.org// The type of filter used on the received packet loss reports.
362dad3fbe492dceacbfc55b2e2e0648be37624b1emarpan@webrtc.orgenum FilterPacketLossMode {
379d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  kNoFilter,   // No filtering on received loss.
389d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  kAvgFilter,  // Recursive average filter.
399d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  kMaxFilter   // Max-window filter, over the time interval of:
409d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel               // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
412dad3fbe492dceacbfc55b2e2e0648be37624b1emarpan@webrtc.org};
422dad3fbe492dceacbfc55b2e2e0648be37624b1emarpan@webrtc.org
43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// Thresholds for hybrid NACK/FEC
44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// common to media optimization and the jitter buffer.
4516825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgconst int64_t kLowRttNackMs = 20;
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
479d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelstruct VCMProtectionParameters {
489d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMProtectionParameters()
499d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel      : rtt(0),
509d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        lossPr(0.0f),
519d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        bitRate(0.0f),
529d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        packetsPerFrame(0.0f),
539d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        packetsPerFrameKey(0.0f),
549d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        frameRate(0.0f),
559d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        keyFrameSize(0.0f),
569d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        fecRateDelta(0),
579d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        fecRateKey(0),
589d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        codecWidth(0),
599d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        codecHeight(0),
609d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel        numLayers(1) {}
619d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
629d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t rtt;
639d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float lossPr;
649d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float bitRate;
659d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float packetsPerFrame;
669d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float packetsPerFrameKey;
679d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float frameRate;
689d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float keyFrameSize;
699d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t fecRateDelta;
709d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t fecRateKey;
719d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint16_t codecWidth;
729d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint16_t codecHeight;
739d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int numLayers;
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/******************************/
77a64300af5043576c3191ba054dd4040f371af737stefan@webrtc.org/* VCMProtectionMethod class  */
78a64300af5043576c3191ba054dd4040f371af737stefan@webrtc.org/******************************/
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
809d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelenum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone };
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
829d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMLossProbabilitySample {
839d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
849d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {}
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
869d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t lossPr255;
879d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t timeMs;
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
909d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMProtectionMethod {
919d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
929d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMProtectionMethod();
939d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual ~VCMProtectionMethod();
949d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
959d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Updates the efficiency of the method using the parameters provided
969d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
979d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
989d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //         - parameters         : Parameters used to calculate efficiency
999d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1009d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : True if this method is recommended in
1019d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //                                the given conditions.
1029d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
1039d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1049d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Returns the protection type
1059d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1069d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : The protection type
1079d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum VCMProtectionMethodEnum Type() const { return _type; }
1089d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1099d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Returns the effective packet loss for ER, required by this protection
1109d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // method
1119d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1129d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : Required effective packet loss
1139d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }
1149d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1159d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Extracts the FEC protection factor for Key frame, required by this
1169d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // protection method
1179d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1189d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : Required protectionFactor for Key frame
1199d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }
1209d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1219d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Extracts the FEC protection factor for Delta frame, required by this
1229d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // protection method
1239d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1249d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : Required protectionFactor for delta frame
1259d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }
1269d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1279d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
1289d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1299d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : Required Unequal protection on/off state.
1309d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }
1319d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1329d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Extracts whether the the FEC Unequal protection (UEP) is used for Delta
1339d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // frame.
1349d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
1359d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : Required Unequal protection on/off state.
1369d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }
1379d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1389d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual int MaxFramesFec() const { return 1; }
1399d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1409d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Updates content metrics
1419d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateContentMetrics(const VideoContentMetrics* contentMetrics);
1429d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1439d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel protected:
1449d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _effectivePacketLoss;
1459d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _protectionFactorK;
1469d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _protectionFactorD;
1479d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Estimation of residual loss after the FEC
1489d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _scaleProtKey;
1499d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int32_t _maxPayloadSize;
1509d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1519d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMQmRobustness* _qmRobustness;
1529d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool _useUepProtectionK;
1539d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool _useUepProtectionD;
1549d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _corrFecCost;
1559d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum VCMProtectionMethodEnum _type;
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1589d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMNackMethod : public VCMProtectionMethod {
1599d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
1609d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMNackMethod();
1619d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual ~VCMNackMethod();
1629d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
1639d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the effective packet loss
1649d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1679d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMFecMethod : public VCMProtectionMethod {
1689d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
1699d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMFecMethod();
1709d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual ~VCMFecMethod();
1719d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
1729d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the effective packet loss for ER
1739d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
1749d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the FEC protection factors
1759d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool ProtectionFactor(const VCMProtectionParameters* parameters);
1769d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the boost for key frame protection
1779d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
1789d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel                           uint8_t packetFrameKey) const;
1799d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Convert the rates: defined relative to total# packets or source# packets
1809d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t ConvertFECRate(uint8_t codeRate) const;
1819d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the average effective recovery from FEC: for random loss model
1829d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
1839d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update FEC with protectionFactorD
1849d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateProtectionFactorD(uint8_t protectionFactorD);
1859d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update FEC with protectionFactorK
1869d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateProtectionFactorK(uint8_t protectionFactorK);
1879d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Compute the bits per frame. Account for temporal layers when applicable.
1889d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int BitsPerFrame(const VCMProtectionParameters* parameters);
1899d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
1909d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel protected:
1919d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum { kUpperLimitFramesFec = 6 };
1929d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Thresholds values for the bytes/frame and round trip time, below which we
1939d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
1949d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
1959d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum { kMaxBytesPerFrameForFec = 700 };
1969d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
1979d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum { kMaxBytesPerFrameForFecLow = 400 };
1989d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
1999d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  enum { kMaxBytesPerFrameForFecHigh = 1000 };
200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2029d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMNackFecMethod : public VCMFecMethod {
2039d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
2049d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMNackFecMethod(int64_t lowRttNackThresholdMs,
2059d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel                   int64_t highRttNackThresholdMs);
2069d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual ~VCMNackFecMethod();
2079d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
2089d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the effective packet loss for ER
2099d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
2109d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the protection factors
2119d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool ProtectionFactor(const VCMProtectionParameters* parameters);
2129d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Get the max number of frames the FEC is allowed to be based on.
2139d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int MaxFramesFec() const;
2149d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Turn off the FEC based on low bitrate and other factors.
2159d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
2169d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2179d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel private:
2189d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
2199d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2209d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _lowRttNackMs;
2219d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _highRttNackMs;
2229d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int _maxFramesFec;
223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2259d3ab61325c5ed216ea52bc829f1d8c81347459bphilipelclass VCMLossProtectionLogic {
2269d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel public:
2279d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  explicit VCMLossProtectionLogic(int64_t nowMs);
2289d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  ~VCMLossProtectionLogic();
2299d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2309d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Set the protection method to be used
2319d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2329d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2339d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //        - newMethodType    : New requested protection method type. If one
2349d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //                           is already set, it will be deleted and replaced
2359d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void SetMethod(VCMProtectionMethodEnum newMethodType);
2369d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2379d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the round-trip time
2389d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2399d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2409d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - rtt           : Round-trip time in seconds.
2419d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateRtt(int64_t rtt);
2429d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2439d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the filtered packet loss.
2449d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2459d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2469d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - packetLossEnc :  The reported packet loss filtered
2479d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //                             (max window or average)
2489d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateFilteredLossPr(uint8_t packetLossEnc);
2499d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2509d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the current target bit rate.
2519d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2529d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2539d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - bitRate          : The current target bit rate in kbits/s
2549d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateBitRate(float bitRate);
2559d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2569d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the number of packets per frame estimate, for delta frames
2579d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2589d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2599d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - nPackets         : Number of packets in the latest sent frame.
2609d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
2619d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2629d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the number of packets per frame estimate, for key frames
2639d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2649d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2659d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - nPackets         : umber of packets in the latest sent frame.
2669d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
2679d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2689d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the keyFrameSize estimate
2699d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2709d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2719d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - keyFrameSize     : The size of the latest sent key frame.
2729d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateKeyFrameSize(float keyFrameSize);
2739d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2749d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the frame rate
2759d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2769d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2779d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - frameRate        : The current target frame rate.
2789d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
2799d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2809d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the frame size
2819d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2829d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2839d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - width        : The codec frame width.
2849d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - height       : The codec frame height.
2859d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateFrameSize(uint16_t width, uint16_t height);
2869d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2879d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the number of active layers
2889d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2899d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2909d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - numLayers    : Number of layers used.
2919d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateNumLayers(int numLayers);
2929d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
2939d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // The amount of packet loss to cover for with FEC.
2949d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
2959d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Input:
2969d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - fecRateKey      : Packet loss to cover for with FEC when
2979d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //                              sending key frames.
2989d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //          - fecRateDelta    : Packet loss to cover for with FEC when
2999d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //                              sending delta frames.
3009d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) {
3019d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel    _fecRateKey = fecRateKey;
3029d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel    _fecRateDelta = fecRateDelta;
3039d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  }
3049d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3059d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Update the protection methods with the current VCMProtectionParameters
3069d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // and set the requested protection settings.
3079d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value     : Returns true on update
3089d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  bool UpdateMethod();
3099d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3109d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Returns the method currently selected.
3119d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  //
3129d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : The protection method currently selected.
3139d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMProtectionMethod* SelectedMethod() const;
3149d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3159d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return the protection type of the currently selected method
3169d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMProtectionMethodEnum SelectedType() const;
3179d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3189d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Updates the filtered loss for the average and max window packet loss,
3199d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // and returns the filtered loss probability in the interval [0, 255].
3209d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // The returned filtered loss value depends on the parameter |filter_mode|.
3219d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // The input parameter |lossPr255| is the received packet loss.
3229d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3239d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Return value                 : The filtered loss probability
3249d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t FilteredLoss(int64_t nowMs,
3259d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel                       FilterPacketLossMode filter_mode,
3269d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel                       uint8_t lossPr255);
3279d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3289d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void Reset(int64_t nowMs);
3299d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3309d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void Release();
3319d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel
3329d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel private:
3339d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  // Sets the available loss protection methods.
3349d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
3359d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t MaxFilteredLossPr(int64_t nowMs) const;
3369d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  rtc::scoped_ptr<VCMProtectionMethod> _selectedMethod;
3379d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMProtectionParameters _currentParameters;
3389d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _rtt;
3399d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _lossPr;
3409d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _bitRate;
3419d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _frameRate;
3429d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  float _keyFrameSize;
3439d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _fecRateKey;
3449d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _fecRateDelta;
3459d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _lastPrUpdateT;
3469d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _lastPacketPerFrameUpdateT;
3479d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int64_t _lastPacketPerFrameUpdateTKey;
3489d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  rtc::ExpFilter _lossPr255;
3499d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
3509d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint8_t _shortMaxLossPr255;
3519d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  rtc::ExpFilter _packetsPerFrame;
3529d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  rtc::ExpFilter _packetsPerFrameKey;
3539d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint16_t _codecWidth;
3549d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  uint16_t _codecHeight;
3559d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel  int _numLayers;
356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com};
357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
358d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace media_optimization
359d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace webrtc
360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3619d3ab61325c5ed216ea52bc829f1d8c81347459bphilipel#endif  // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
362