Added simple model to test_util.cc to simulate bursty packet loss.

Review URL: http://webrtc-codereview.appspot.com/104002

git-svn-id: http://webrtc.googlecode.com/svn/trunk@355 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
marpan@google.com 2011-08-11 22:51:58 +00:00
parent 60873adc3e
commit 319fbd107d
2 changed files with 72 additions and 6 deletions

View File

@ -236,6 +236,8 @@ RTPSendCompleteCallback::RTPSendCompleteCallback(RtpRtcp* rtp, const char* filen
_sendCount(0), _sendCount(0),
_rtp(rtp), _rtp(rtp),
_lossPct(0), _lossPct(0),
_burstLength(0),
_prevLossState(0),
_rtpDump(NULL) _rtpDump(NULL)
{ {
if (filename != NULL) if (filename != NULL)
@ -256,14 +258,67 @@ int
RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len) RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
{ {
_sendCount++; _sendCount++;
// Packet Loss - randomly drop %loss packets
// don't drop I-frame packets // Packet Loss
if(PacketLoss(_lossPct) && (_sendCount > 12))
if (_burstLength <= 1.0)
{ {
// drop // Random loss: if _burstLength parameter is not set, or <=1
//printf("\tDrop packet, sendCount = %d\n", _sendCount); if (PacketLoss(_lossPct))
return len; {
// drop
//printf("\tDrop packet, sendCount = %d\n", _sendCount);
return len;
}
} }
else
{
// Simulate bursty channel (Gilbert model)
// (1st order) Markov chain model with memory of the previous/last
// packet state (loss or received)
// 0 = received state
// 1 = loss state
// probTrans10: if previous packet is lost, prob. to -> received state
// probTrans11: if previous packet is lost, prob. to -> loss state
// probTrans01: if previous packet is received, prob. to -> loss state
// probTrans00: if previous packet is received, prob. to -> received
// Map the two channel parameters (average loss rate and burst length)
// to the transition probabilities:
double probTrans10 = 100 * (1.0 / _burstLength);
double probTrans11 = (100.0 - probTrans10);
double probTrans01 = (probTrans10 * ( _lossPct / (100.0 - _lossPct) ) );
// Note: Random loss (Bernoulli) model is a special case where:
// burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100)
if (_prevLossState == 0 )
{
// previous packet was received
if (PacketLoss(probTrans01) )
{
// drop, update previous state to loss
_prevLossState = 1;
return len;
}
}
else if (_prevLossState == 1)
{
// previous packet was lost
if (PacketLoss(probTrans11) )
{
// drop, update previous state to loss
_prevLossState = 1;
return len;
}
}
// no drop, update previous state to received
_prevLossState = 0;
}
if (_rtpDump != NULL) if (_rtpDump != NULL)
{ {
if (_rtpDump->DumpPacket((const WebRtc_UWord8*)data, len) != 0) if (_rtpDump->DumpPacket((const WebRtc_UWord8*)data, len) != 0)
@ -295,6 +350,13 @@ RTPSendCompleteCallback::SetLossPct(double lossPct)
return; return;
} }
void
RTPSendCompleteCallback::SetBurstLength(double burstLength)
{
_burstLength = burstLength;
return;
}
bool bool
RTPSendCompleteCallback::PacketLoss(double lossPct) RTPSendCompleteCallback::PacketLoss(double lossPct)
{ {

View File

@ -185,6 +185,8 @@ public:
virtual int SendRTCPPacket(int channel, const void *data, int len); virtual int SendRTCPPacket(int channel, const void *data, int len);
// Set percentage of channel loss in the network // Set percentage of channel loss in the network
void SetLossPct(double lossPct); void SetLossPct(double lossPct);
// Set average size of burst loss
void SetBurstLength(double burstLength);
// return send count // return send count
int SendCount() { return _sendCount; } int SendCount() { return _sendCount; }
private: private:
@ -194,6 +196,8 @@ private:
WebRtc_UWord32 _sendCount; WebRtc_UWord32 _sendCount;
webrtc::RtpRtcp* _rtp; webrtc::RtpRtcp* _rtp;
double _lossPct; double _lossPct;
double _burstLength;
bool _prevLossState;
webrtc::RtpDump* _rtpDump; webrtc::RtpDump* _rtpDump;
}; };