Fix infinite loop bug introduced in r1174.

Merges CleanUpSizeZeroFrames with CleanUpOldFrames, and changes the
behavior to go through all frames looking for empty frames.

TBR=mikhals

BUG=
TEST=

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1186 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org
2011-12-14 15:55:19 +00:00
parent 9fe3d51372
commit 780a07a843
2 changed files with 3 additions and 88 deletions

View File

@@ -325,8 +325,8 @@ VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
// an old complete frame can arrive too late // an old complete frame can arrive too late
if (_lastDecodedState.IsOldFrame(frame)) if (_lastDecodedState.IsOldFrame(frame))
{ {
// Frame is older than the latest decoded frame, drop it. // Frame is older than the latest decoded frame, drop it. Will be
// This will trigger a release in CleanUpSizeZeroFrames later. // released by CleanUpOldFrames later.
frame->Reset(); frame->Reset();
frame->SetState(kStateEmpty); frame->SetState(kStateEmpty);
@@ -679,7 +679,6 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
_critSect->Enter(); _critSect->Enter();
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
if (_lastDecodedState.init() && WaitForNack()) { if (_lastDecodedState.init() && WaitForNack()) {
_waitingForKeyFrame = true; _waitingForKeyFrame = true;
@@ -720,7 +719,6 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
// Finding oldest frame ready for decoder, but check // Finding oldest frame ready for decoder, but check
// sequence number and size // sequence number and size
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
oldestFrameListItem = FindOldestCompleteContinuousFrame(false); oldestFrameListItem = FindOldestCompleteContinuousFrame(false);
if (oldestFrameListItem != NULL) if (oldestFrameListItem != NULL)
{ {
@@ -774,7 +772,6 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
oldestFrame->SetState(kStateDecoding); oldestFrame->SetState(kStateDecoding);
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey) if (oldestFrame->FrameType() == kVideoFrameKey)
{ {
@@ -838,7 +835,6 @@ VCMJitterBuffer::GetNextTimeStamp(WebRtc_UWord32 maxWaitTimeMS,
// Finding oldest frame ready for decoder, check sequence number and size // Finding oldest frame ready for decoder, check sequence number and size
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
VCMFrameBuffer* oldestFrame = _frameBuffersTSOrder.FirstFrame(); VCMFrameBuffer* oldestFrame = _frameBuffersTSOrder.FirstFrame();
@@ -857,7 +853,6 @@ VCMJitterBuffer::GetNextTimeStamp(WebRtc_UWord32 maxWaitTimeMS,
_critSect->Enter(); _critSect->Enter();
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
oldestFrame = _frameBuffersTSOrder.FirstFrame(); oldestFrame = _frameBuffersTSOrder.FirstFrame();
} }
else else
@@ -898,7 +893,6 @@ VCMJitterBuffer::CompleteSequenceWithNextFrame()
CriticalSectionScoped cs(_critSect); CriticalSectionScoped cs(_critSect);
// Finding oldest frame ready for decoder, check sequence number and size // Finding oldest frame ready for decoder, check sequence number and size
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
VCMFrameListItem* oldestFrameListItem = _frameBuffersTSOrder.First(); VCMFrameListItem* oldestFrameListItem = _frameBuffersTSOrder.First();
if (oldestFrameListItem == NULL) if (oldestFrameListItem == NULL)
@@ -956,7 +950,6 @@ VCMJitterBuffer::GetFrameForDecoding()
} }
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
VCMFrameListItem* oldestFrameListItem = _frameBuffersTSOrder.First(); VCMFrameListItem* oldestFrameListItem = _frameBuffersTSOrder.First();
if (oldestFrameListItem == NULL) if (oldestFrameListItem == NULL)
@@ -1009,7 +1002,6 @@ VCMJitterBuffer::GetFrameForDecoding()
oldestFrame->SetState(kStateDecoding); oldestFrame->SetState(kStateDecoding);
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey) if (oldestFrame->FrameType() == kVideoFrameKey)
{ {
@@ -1033,7 +1025,6 @@ VCMJitterBuffer::GetFrameForDecodingNACK()
// Clean up old frames and empty frames // Clean up old frames and empty frames
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
// First look for a complete _continuous_ frame. // First look for a complete _continuous_ frame.
// When waiting for nack, wait for a key frame, if a continuous frame cannot // When waiting for nack, wait for a key frame, if a continuous frame cannot
@@ -1089,7 +1080,6 @@ VCMJitterBuffer::GetFrameForDecodingNACK()
// Clean up old frames and empty frames // Clean up old frames and empty frames
CleanUpOldFrames(); CleanUpOldFrames();
CleanUpSizeZeroFrames();
if (oldestFrame->FrameType() == kVideoFrameKey) if (oldestFrame->FrameType() == kVideoFrameKey)
{ {
@@ -1604,9 +1594,9 @@ VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
case kTimeStampError: case kTimeStampError:
case kSizeError: case kSizeError:
{ {
// This will trigger a release in CleanUpSizeZeroFrames
if (frame != NULL) if (frame != NULL)
{ {
// Will be released when it gets old.
frame->Reset(); frame->Reset();
frame->SetState(kStateEmpty); frame->SetState(kStateEmpty);
} }
@@ -1755,53 +1745,6 @@ VCMJitterBuffer::RecycleFramesUntilKeyFrame()
return foundKeyFrame; return foundKeyFrame;
} }
// Must be called under the critical section _critSect.
VCMFrameListItem*
VCMJitterBuffer::FindOldestSequenceNum() const
{
WebRtc_UWord16 currentLow = 0xffff;
WebRtc_UWord16 sequenceNumber = 0;
bool first = true;
VCMFrameListItem* frameListItem = _frameBuffersTSOrder.First();
VCMFrameListItem* oldestFrameListItem = NULL;
while (frameListItem != NULL)
{
// if we have more than one frame done since last time,
// pick oldest
VCMFrameBuffer* ptrFrame = NULL;
ptrFrame = frameListItem->GetItem();
sequenceNumber = static_cast<WebRtc_UWord16>(ptrFrame->GetLowSeqNum());
// Find the oldest, hence lowest, using sequence numbers
if (first)
{
currentLow = sequenceNumber;
oldestFrameListItem = frameListItem;
first = false;
}
else if ((currentLow < 0x0fff) && (sequenceNumber > 0xf000))
{
// We have a wrap and this one is older
currentLow = sequenceNumber;
oldestFrameListItem = frameListItem;
}
else if ((sequenceNumber < 0x0fff) && (currentLow > 0xf000))
{
// This one is after a wrap, leave as is
}
else if (currentLow > sequenceNumber)
{
// Normal case, this one is lower.
currentLow = sequenceNumber;
oldestFrameListItem = frameListItem;
}
frameListItem = _frameBuffersTSOrder.Next(frameListItem);
}
return oldestFrameListItem;
}
// Must be called under the critical section _critSect. // Must be called under the critical section _critSect.
void VCMJitterBuffer::CleanUpOldFrames() { void VCMJitterBuffer::CleanUpOldFrames() {
if (_lastDecodedState.init()) if (_lastDecodedState.init())
@@ -1822,32 +1765,6 @@ void VCMJitterBuffer::CleanUpOldFrames() {
} }
} }
// TODO (mikhal):
// 1. Merge with previous function.
// 2. Modify to use timestamps and not seqnum.
// Must be called under _critSect.
void VCMJitterBuffer::CleanUpSizeZeroFrames() {
VCMFrameListItem* frameListItem = FindOldestSequenceNum();
while (frameListItem != NULL) {
VCMFrameBuffer* ptrTempBuffer = frameListItem->GetItem();
// Pop frame if its size zero but store seqnum.
if (ptrTempBuffer->Length() == 0) {
WebRtc_Word32 frameHighSeqNum = ptrTempBuffer->GetHighSeqNum();
if (frameHighSeqNum == -1) {
// This frame has been Reset for this function to clean it up
_frameBuffersTSOrder.Erase(frameListItem);
ReleaseFrameInternal(ptrTempBuffer);
frameListItem = FindOldestSequenceNum();
}
} else {
// we have a length
break;
}
}
}
// Used in GetFrameForDecoding // Used in GetFrameForDecoding
void VCMJitterBuffer::VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame) { void VCMJitterBuffer::VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame) {
frame.MakeSessionDecodable(); // Make sure the session can be decoded. frame.MakeSessionDecodable(); // Make sure the session can be decoded.

View File

@@ -161,7 +161,6 @@ private:
VCMFrameListItem* FindOldestCompleteContinuousFrame(bool enableDecodable); VCMFrameListItem* FindOldestCompleteContinuousFrame(bool enableDecodable);
void CleanUpOldFrames(); void CleanUpOldFrames();
void CleanUpSizeZeroFrames();
void VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame); void VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame);
bool IsPacketRetransmitted(const VCMPacket& packet) const; bool IsPacketRetransmitted(const VCMPacket& packet) const;
@@ -189,7 +188,6 @@ private:
const void* notUsed); const void* notUsed);
// Decide whether should wait for NACK (mainly relevant for hybrid mode) // Decide whether should wait for NACK (mainly relevant for hybrid mode)
bool WaitForNack(); bool WaitForNack();
VCMFrameListItem* FindOldestSequenceNum() const;
WebRtc_Word32 _vcmId; WebRtc_Word32 _vcmId;
WebRtc_Word32 _receiverId; WebRtc_Word32 _receiverId;