Fixes two jitter buffer bugs related to NACK.

Avoid decoding delta frames after a Flush() and after requesting
a key frame due to full NACK list.

BUG=
TEST=

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@837 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2011-10-28 16:00:49 +00:00
parent 35a12cdf60
commit f960211f8b
2 changed files with 25 additions and 1 deletions

View File

@ -88,6 +88,7 @@ VCMJitterBuffer::VCMJitterBuffer(WebRtc_Word32 vcmId, WebRtc_Word32 receiverId,
_nackMode(kNoNack), _nackMode(kNoNack),
_NACKSeqNum(), _NACKSeqNum(),
_NACKSeqNumLength(0), _NACKSeqNumLength(0),
_waitingForKeyFrame(false),
_firstPacket(true) _firstPacket(true)
{ {
memset(_frameBuffers, 0, sizeof(_frameBuffers)); memset(_frameBuffers, 0, sizeof(_frameBuffers));
@ -140,6 +141,7 @@ VCMJitterBuffer::operator=(const VCMJitterBuffer& rhs)
_nackMode = rhs._nackMode; _nackMode = rhs._nackMode;
_rttMs = rhs._rttMs; _rttMs = rhs._rttMs;
_NACKSeqNumLength = rhs._NACKSeqNumLength; _NACKSeqNumLength = rhs._NACKSeqNumLength;
_waitingForKeyFrame = rhs._waitingForKeyFrame;
_firstPacket = rhs._firstPacket; _firstPacket = rhs._firstPacket;
_lastDecodedSeqNum = rhs._lastDecodedSeqNum; _lastDecodedSeqNum = rhs._lastDecodedSeqNum;
_lastDecodedTimeStamp = rhs._lastDecodedTimeStamp; _lastDecodedTimeStamp = rhs._lastDecodedTimeStamp;
@ -197,6 +199,7 @@ VCMJitterBuffer::Start()
_waitingForCompletion.latestPacketTime = -1; _waitingForCompletion.latestPacketTime = -1;
_firstPacket = true; _firstPacket = true;
_NACKSeqNumLength = 0; _NACKSeqNumLength = 0;
_waitingForKeyFrame = false;
_rttMs = 0; _rttMs = 0;
_packetsNotDecodable = 0; _packetsNotDecodable = 0;
@ -614,7 +617,7 @@ VCMJitterBuffer::FindOldestCompleteContinuousFrame()
// we have a complete frame // we have a complete frame
// check if it's continuous, otherwise we are missing a full frame // check if it's continuous, otherwise we are missing a full frame
// Use seqNum not timestamp since a full frame might be lost // Use seqNum not timestamp since a full frame might be lost
if (_lastDecodedSeqNum != -1) if (_lastDecodedSeqNum != -1 && !_waitingForKeyFrame)
{ {
// it's not enough that we have complete frame we need the layers to // it's not enough that we have complete frame we need the layers to
// be continuous too // be continuous too
@ -630,6 +633,10 @@ VCMJitterBuffer::FindOldestCompleteContinuousFrame()
return NULL; return NULL;
} }
} }
else if (oldestFrame->FrameType() != kVideoFrameKey)
{
return NULL;
}
return oldestFrameItem; return oldestFrameItem;
} }
@ -825,6 +832,11 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames(); CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey)
{
_waitingForKeyFrame = false;
}
_critSect.Leave(); _critSect.Leave();
// We have a frame - store seqnum & timestamp // We have a frame - store seqnum & timestamp
@ -1061,6 +1073,11 @@ VCMJitterBuffer::GetFrameForDecoding()
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames(); CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey)
{
_waitingForKeyFrame = false;
}
_packetsNotDecodable += oldestFrame->NotDecodablePackets(); _packetsNotDecodable += oldestFrame->NotDecodablePackets();
// Store current seqnum & time // Store current seqnum & time
@ -1129,6 +1146,11 @@ VCMJitterBuffer::GetFrameForDecodingNACK()
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames(); CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey)
{
_waitingForKeyFrame = false;
}
// We have a complete/decodable continuous frame, decode it. // We have a complete/decodable continuous frame, decode it.
// Store seqnum & timestamp // Store seqnum & timestamp
_lastDecodedSeqNum = oldestFrame->GetHighSeqNum(); _lastDecodedSeqNum = oldestFrame->GetHighSeqNum();
@ -1386,6 +1408,7 @@ VCMJitterBuffer::CreateNackList(WebRtc_UWord16& nackSize, bool& listExtended)
// Set the last decoded sequence number to current high. // Set the last decoded sequence number to current high.
// This is to not get a large nack list again right away // This is to not get a large nack list again right away
_lastDecodedSeqNum = highSeqNum; _lastDecodedSeqNum = highSeqNum;
_waitingForKeyFrame = true;
// Set to trigger key frame signal // Set to trigger key frame signal
nackSize = 0xffff; nackSize = 0xffff;
listExtended = true; listExtended = true;

View File

@ -238,6 +238,7 @@ private:
WebRtc_Word32 _NACKSeqNumInternal[kNackHistoryLength]; WebRtc_Word32 _NACKSeqNumInternal[kNackHistoryLength];
WebRtc_UWord16 _NACKSeqNum[kNackHistoryLength]; WebRtc_UWord16 _NACKSeqNum[kNackHistoryLength];
WebRtc_UWord32 _NACKSeqNumLength; WebRtc_UWord32 _NACKSeqNumLength;
bool _waitingForKeyFrame;
bool _firstPacket; bool _firstPacket;
}; };