Fix issues with sequence number wrap-around in jitter statistics

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
This commit is contained in:
henrik.lundin@webrtc.org
2013-11-21 13:17:29 +00:00
parent b3cc78de28
commit 6f6ba6edee
3 changed files with 99 additions and 8 deletions

View File

@ -28,6 +28,17 @@
extern FILE *delay_fid2; /* file pointer to delay log file */
#endif /* NETEQ_DELAY_LOGGING */
// These two functions are copied from module_common_types.h, but adapted for C.
int WebRtcNetEQ_IsNewerSequenceNumber(uint16_t sequence_number,
uint16_t prev_sequence_number) {
return sequence_number != prev_sequence_number &&
((uint16_t) (sequence_number - prev_sequence_number)) < 0x8000;
}
int WebRtcNetEQ_IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
return timestamp != prev_timestamp &&
((uint32_t) (timestamp - prev_timestamp)) < 0x80000000;
}
int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
uint16_t seqNumber, uint32_t timeStamp,
@ -55,7 +66,8 @@ int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
/****************************/
/* Try calculating packet length from current and previous timestamps */
if ((timeStamp <= inst->lastTimeStamp) || (seqNumber <= inst->lastSeqNo))
if (!WebRtcNetEQ_IsNewerTimestamp(timeStamp, inst->lastTimeStamp) ||
!WebRtcNetEQ_IsNewerSequenceNumber(seqNumber, inst->lastSeqNo))
{
/* Wrong timestamp or sequence order; revert to backup plan */
packetLenSamp = inst->packetSpeechLenSamp; /* use stored value */
@ -68,7 +80,7 @@ int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
}
/* Check that the packet size is positive; if not, the statistics cannot be updated. */
if (packetLenSamp > 0)
if (inst->firstPacketReceived && packetLenSamp > 0)
{ /* packet size ok */
/* calculate inter-arrival time in integer packets (rounding down) */
@ -113,19 +125,19 @@ int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
} /* end of streaming mode */
/* check for discontinuous packet sequence and re-ordering */
if (seqNumber > inst->lastSeqNo + 1)
if (WebRtcNetEQ_IsNewerSequenceNumber(seqNumber, inst->lastSeqNo + 1))
{
/* Compensate for gap in the sequence numbers.
* Reduce IAT with expected extra time due to lost packets, but ensure that
* the IAT is not negative.
*/
timeIat -= WEBRTC_SPL_MIN(timeIat,
(uint32_t) (seqNumber - inst->lastSeqNo - 1));
(uint16_t) (seqNumber - (uint16_t) (inst->lastSeqNo + 1)));
}
else if (seqNumber < inst->lastSeqNo)
else if (!WebRtcNetEQ_IsNewerSequenceNumber(seqNumber, inst->lastSeqNo))
{
/* compensate for re-ordering */
timeIat += (uint32_t) (inst->lastSeqNo + 1 - seqNumber);
timeIat += (uint16_t) (inst->lastSeqNo + 1 - seqNumber);
}
/* saturate IAT at maximum value */
@ -316,6 +328,8 @@ int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen,
inst->lastTimeStamp = timeStamp; /* remember current timestamp */
inst->firstPacketReceived = 1;
return retval;
}