
Wrap-arounds in sequence numbers (and in timestamps) were not always treated correctly. This is fixed by introducing two helper functions for correct comparisons, and by casting to the right word size. Also added a new member variable to AutomodeInst_t. The new member keeps track of when the first packet has been registered in the automode code. This was previously done implicitly (and not very good) using the fact that the lastSeqNo and lastTimestamp members were initialized to zero. Two new unit tests were added as part of this CL. NetEqDecodingTest.SequenceNumberWrap was failing before the fixes were made; now it is ok. BUG=2654 R=tina.legrand@webrtc.org Review URL: https://webrtc-codereview.appspot.com/4139004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5150 4adac7df-926f-26a2-2b94-8c16560cd09d
275 lines
10 KiB
C
275 lines
10 KiB
C
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
/*
|
|
* This file contains the functionality for automatic buffer level optimization.
|
|
*/
|
|
|
|
#ifndef AUTOMODE_H
|
|
#define AUTOMODE_H
|
|
|
|
#include "typedefs.h"
|
|
|
|
/*************/
|
|
/* Constants */
|
|
/*************/
|
|
|
|
/* The beta parameter defines the trade-off between delay and underrun probability. */
|
|
/* It is defined through its inverse in Q30 */
|
|
#define AUTOMODE_BETA_INV_Q30 53687091 /* 1/20 in Q30 */
|
|
#define AUTOMODE_STREAMING_BETA_INV_Q30 536871 /* 1/2000 in Q30 */
|
|
|
|
/* Forgetting factor for the inter-arrival time statistics */
|
|
#define IAT_PROB_FACT 32745 /* 0.9993 in Q15 */
|
|
|
|
/* Maximum inter-arrival time to register (in "packet-times") */
|
|
#define MAX_IAT 64
|
|
#define PEAK_HEIGHT 20 /* 0.08s in Q8 */
|
|
|
|
/* The value (1<<5) sets maximum accelerate "speed" to about 100 ms/s */
|
|
#define AUTOMODE_TIMESCALE_LIMIT (1<<5)
|
|
|
|
/* Peak mode related parameters */
|
|
/* Number of peaks in peak vector; must be a power of 2 */
|
|
#define NUM_PEAKS 8
|
|
|
|
/* Must be NUM_PEAKS-1 */
|
|
#define PEAK_INDEX_MASK 0x0007
|
|
|
|
/* Longest accepted peak distance */
|
|
#define MAX_PEAK_PERIOD 10
|
|
#define MAX_STREAMING_PEAK_PERIOD 600 /* 10 minutes */
|
|
|
|
/* Number of peaks required before peak mode can be engaged */
|
|
#define NUM_PEAKS_REQUIRED 3
|
|
|
|
/* Drift term for cumulative sum */
|
|
#define CSUM_IAT_DRIFT 2
|
|
|
|
/*******************/
|
|
/* Automode struct */
|
|
/*******************/
|
|
|
|
/* The automode struct is a sub-struct of the
|
|
bufstats-struct (BufstatsInst_t). */
|
|
|
|
typedef struct
|
|
{
|
|
|
|
/* Filtered current buffer level */
|
|
uint16_t levelFiltFact; /* filter forgetting factor in Q8 */
|
|
int buffLevelFilt; /* filtered buffer level in Q8 */
|
|
|
|
/* Inter-arrival time (iat) statistics */
|
|
int32_t iatProb[MAX_IAT + 1]; /* iat probabilities in Q30 */
|
|
int16_t iatProbFact; /* iat forgetting factor in Q15 */
|
|
uint32_t packetIatCountSamp; /* time (in timestamps) elapsed since last
|
|
packet arrival, based on RecOut calls */
|
|
int optBufLevel; /* current optimal buffer level in Q8 */
|
|
|
|
/* Packet related information */
|
|
int16_t packetSpeechLenSamp; /* speech samples per incoming packet */
|
|
int16_t lastPackCNGorDTMF; /* indicates that the last received packet
|
|
contained special information */
|
|
uint16_t lastSeqNo; /* sequence number for last packet received */
|
|
uint32_t lastTimeStamp; /* timestamp for the last packet received */
|
|
int firstPacketReceived; /* set to zero implicitly when the instance is
|
|
filled with zeros */
|
|
int32_t sampleMemory; /* memory position for keeping track of how many
|
|
samples we cut during expand */
|
|
int16_t prevTimeScale; /* indicates that the last mode was an accelerate
|
|
or pre-emptive expand operation */
|
|
uint32_t timescaleHoldOff; /* counter that is shifted one step right each
|
|
RecOut call; time-scaling allowed when it has
|
|
reached 0 */
|
|
int16_t extraDelayMs; /* extra delay for sync with video */
|
|
|
|
int minimum_delay_ms; /* Desired delay, NetEq maintains this amount of
|
|
delay unless jitter statistics suggests a higher value. */
|
|
int maximum_delay_ms; /* Max desired delay, NetEq will not go above this
|
|
amount of delay even if jitter statistics suggests a higher value. */
|
|
|
|
int required_delay_q8; /* Smallest delay required. This is computed
|
|
according to inter-arrival time and playout mode. It has the same unit
|
|
as |optBufLevel|. */
|
|
|
|
/* Peak-detection */
|
|
/* vector with the latest peak periods (peak spacing in samples) */
|
|
uint32_t peakPeriodSamp[NUM_PEAKS];
|
|
/* vector with the latest peak heights (in packets) */
|
|
int16_t peakHeightPkt[NUM_PEAKS];
|
|
int16_t peakIndex; /* index for the vectors peakPeriodSamp and peakHeightPkt;
|
|
-1 if still waiting for first peak */
|
|
uint16_t peakThresholdPkt; /* definition of peak (in packets);
|
|
calculated from PEAK_HEIGHT */
|
|
uint32_t peakIatCountSamp; /* samples elapsed since last peak was observed */
|
|
uint32_t curPeakPeriod; /* current maximum of peakPeriodSamp vector */
|
|
int16_t curPeakHeight; /* derived from peakHeightPkt vector;
|
|
used as optimal buffer level in peak mode */
|
|
int16_t peakModeDisabled; /* ==0 if peak mode can be engaged; >0 if not */
|
|
uint16_t peakFound; /* 1 if peaks are detected and extra delay is applied;
|
|
* 0 otherwise. */
|
|
|
|
/* Post-call statistics */
|
|
uint32_t countIAT500ms; /* number of times we got small network outage */
|
|
uint32_t countIAT1000ms; /* number of times we got medium network outage */
|
|
uint32_t countIAT2000ms; /* number of times we got large network outage */
|
|
uint32_t longestIATms; /* mSec duration of longest network outage */
|
|
|
|
int16_t cSumIatQ8; /* cumulative sum of inter-arrival times */
|
|
int16_t maxCSumIatQ8; /* max cumulative sum IAT */
|
|
uint32_t maxCSumUpdateTimer;/* time elapsed since maximum was observed */
|
|
} AutomodeInst_t;
|
|
|
|
/*************/
|
|
/* Functions */
|
|
/*************/
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_UpdateIatStatistics(...)
|
|
*
|
|
* Update the packet inter-arrival time statistics when a new packet arrives.
|
|
* This function should be called for every arriving packet, with some
|
|
* exceptions when using DTX/VAD and DTMF. A new optimal buffer level is
|
|
* calculated after the update.
|
|
*
|
|
* Input:
|
|
* - inst : Automode instance
|
|
* - maxBufLen : Maximum number of packets the buffer can hold
|
|
* - seqNumber : RTP sequence number of incoming packet
|
|
* - timeStamp : RTP timestamp of incoming packet
|
|
* - fsHz : Sample rate in Hz
|
|
* - mdCodec : Non-zero if the current codec is a multiple-
|
|
* description codec
|
|
* - streamingMode : A non-zero value will increase jitter robustness (and delay)
|
|
*
|
|
* Output:
|
|
* - inst : Updated automode instance
|
|
*
|
|
* Return value : 0 - Ok
|
|
* <0 - Error
|
|
*/
|
|
|
|
int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
|
|
uint16_t seqNumber, uint32_t timeStamp,
|
|
int32_t fsHz, int mdCodec, int streamingMode);
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_CalcOptimalBufLvl(...)
|
|
*
|
|
* Calculate the optimal buffer level based on packet inter-arrival time
|
|
* statistics.
|
|
*
|
|
* Input:
|
|
* - inst : Automode instance
|
|
* - fsHz : Sample rate in Hz
|
|
* - mdCodec : Non-zero if the current codec is a multiple-
|
|
* description codec
|
|
* - timeIatPkts : Currently observed inter-arrival time in packets
|
|
* - streamingMode : A non-zero value will increase jitter robustness (and delay)
|
|
*
|
|
* Output:
|
|
* - inst : Updated automode instance
|
|
*
|
|
* Return value : >0 - Optimal buffer level
|
|
* <0 - Error
|
|
*/
|
|
|
|
int16_t WebRtcNetEQ_CalcOptimalBufLvl(AutomodeInst_t *inst, int32_t fsHz,
|
|
int mdCodec, uint32_t timeIatPkts,
|
|
int streamingMode);
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_BufferLevelFilter(...)
|
|
*
|
|
* Update filtered buffer level. The function must be called once for each
|
|
* RecOut call, since the timing of automode hinges on counters that are
|
|
* updated by this function.
|
|
*
|
|
* Input:
|
|
* - curSizeMs8 : Total length of unused speech data in packet buffer
|
|
* and sync buffer, in ms * 8
|
|
* - inst : Automode instance
|
|
* - sampPerCall : Number of samples per RecOut call
|
|
* - fsMult : Sample rate in Hz divided by 8000
|
|
*
|
|
* Output:
|
|
* - inst : Updated automode instance
|
|
*
|
|
* Return value : 0 - Ok
|
|
* : <0 - Error
|
|
*/
|
|
|
|
int WebRtcNetEQ_BufferLevelFilter(int32_t curSizeMs8, AutomodeInst_t *inst,
|
|
int sampPerCall, int16_t fsMult);
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_SetPacketSpeechLen(...)
|
|
*
|
|
* Provide the number of speech samples extracted from a packet to the
|
|
* automode instance. Several of the calculations within automode depend
|
|
* on knowing the packet size.
|
|
*
|
|
*
|
|
* Input:
|
|
* - inst : Automode instance
|
|
* - newLenSamp : Number of samples per RecOut call
|
|
* - fsHz : Sample rate in Hz
|
|
*
|
|
* Output:
|
|
* - inst : Updated automode instance
|
|
*
|
|
* Return value : 0 - Ok
|
|
* <0 - Error
|
|
*/
|
|
|
|
int WebRtcNetEQ_SetPacketSpeechLen(AutomodeInst_t *inst, int16_t newLenSamp,
|
|
int32_t fsHz);
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_ResetAutomode(...)
|
|
*
|
|
* Reset the automode instance.
|
|
*
|
|
*
|
|
* Input:
|
|
* - inst : Automode instance
|
|
* - maxBufLenPackets : Maximum number of packets that the packet
|
|
* buffer can hold (>1)
|
|
*
|
|
* Output:
|
|
* - inst : Updated automode instance
|
|
*
|
|
* Return value : 0 - Ok
|
|
*/
|
|
|
|
int WebRtcNetEQ_ResetAutomode(AutomodeInst_t *inst, int maxBufLenPackets);
|
|
|
|
/****************************************************************************
|
|
* WebRtcNetEQ_AverageIAT(...)
|
|
*
|
|
* Calculate the average inter-arrival time based on current statistics.
|
|
* The average is expressed in parts per million relative the nominal. That is,
|
|
* if the average inter-arrival time is equal to the nominal frame time,
|
|
* the return value is zero. A positive value corresponds to packet spacing
|
|
* being too large, while a negative value means that the packets arrive with
|
|
* less spacing than expected.
|
|
*
|
|
*
|
|
* Input:
|
|
* - inst : Automode instance.
|
|
*
|
|
* Return value : Average relative inter-arrival time in samples.
|
|
*/
|
|
|
|
int32_t WebRtcNetEQ_AverageIAT(const AutomodeInst_t *inst);
|
|
|
|
#endif /* AUTOMODE_H */
|