From f960211f8b5aa8f3c7fc79dadb22cb6d241132c7 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Fri, 28 Oct 2011 16:00:49 +0000 Subject: [PATCH] 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 --- .../video_coding/main/source/jitter_buffer.cc | 25 ++++++++++++++++++- .../video_coding/main/source/jitter_buffer.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/modules/video_coding/main/source/jitter_buffer.cc b/src/modules/video_coding/main/source/jitter_buffer.cc index 653af4fdf..b855fcba0 100644 --- a/src/modules/video_coding/main/source/jitter_buffer.cc +++ b/src/modules/video_coding/main/source/jitter_buffer.cc @@ -88,6 +88,7 @@ VCMJitterBuffer::VCMJitterBuffer(WebRtc_Word32 vcmId, WebRtc_Word32 receiverId, _nackMode(kNoNack), _NACKSeqNum(), _NACKSeqNumLength(0), + _waitingForKeyFrame(false), _firstPacket(true) { memset(_frameBuffers, 0, sizeof(_frameBuffers)); @@ -140,6 +141,7 @@ VCMJitterBuffer::operator=(const VCMJitterBuffer& rhs) _nackMode = rhs._nackMode; _rttMs = rhs._rttMs; _NACKSeqNumLength = rhs._NACKSeqNumLength; + _waitingForKeyFrame = rhs._waitingForKeyFrame; _firstPacket = rhs._firstPacket; _lastDecodedSeqNum = rhs._lastDecodedSeqNum; _lastDecodedTimeStamp = rhs._lastDecodedTimeStamp; @@ -197,6 +199,7 @@ VCMJitterBuffer::Start() _waitingForCompletion.latestPacketTime = -1; _firstPacket = true; _NACKSeqNumLength = 0; + _waitingForKeyFrame = false; _rttMs = 0; _packetsNotDecodable = 0; @@ -614,7 +617,7 @@ VCMJitterBuffer::FindOldestCompleteContinuousFrame() // we have a complete frame // check if it's continuous, otherwise we are missing a full frame // 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 // be continuous too @@ -630,6 +633,10 @@ VCMJitterBuffer::FindOldestCompleteContinuousFrame() return NULL; } } + else if (oldestFrame->FrameType() != kVideoFrameKey) + { + return NULL; + } return oldestFrameItem; } @@ -825,6 +832,11 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS) CleanUpOldFrames(); CleanUpSizeZeroFrames(); + if (oldestFrame->FrameType() == kVideoFrameKey) + { + _waitingForKeyFrame = false; + } + _critSect.Leave(); // We have a frame - store seqnum & timestamp @@ -1061,6 +1073,11 @@ VCMJitterBuffer::GetFrameForDecoding() CleanUpOldFrames(); CleanUpSizeZeroFrames(); + if (oldestFrame->FrameType() == kVideoFrameKey) + { + _waitingForKeyFrame = false; + } + _packetsNotDecodable += oldestFrame->NotDecodablePackets(); // Store current seqnum & time @@ -1129,6 +1146,11 @@ VCMJitterBuffer::GetFrameForDecodingNACK() CleanUpOldFrames(); CleanUpSizeZeroFrames(); + if (oldestFrame->FrameType() == kVideoFrameKey) + { + _waitingForKeyFrame = false; + } + // We have a complete/decodable continuous frame, decode it. // Store seqnum & timestamp _lastDecodedSeqNum = oldestFrame->GetHighSeqNum(); @@ -1386,6 +1408,7 @@ VCMJitterBuffer::CreateNackList(WebRtc_UWord16& nackSize, bool& listExtended) // Set the last decoded sequence number to current high. // This is to not get a large nack list again right away _lastDecodedSeqNum = highSeqNum; + _waitingForKeyFrame = true; // Set to trigger key frame signal nackSize = 0xffff; listExtended = true; diff --git a/src/modules/video_coding/main/source/jitter_buffer.h b/src/modules/video_coding/main/source/jitter_buffer.h index 8ac8cd63b..7e97e6bfe 100644 --- a/src/modules/video_coding/main/source/jitter_buffer.h +++ b/src/modules/video_coding/main/source/jitter_buffer.h @@ -238,6 +238,7 @@ private: WebRtc_Word32 _NACKSeqNumInternal[kNackHistoryLength]; WebRtc_UWord16 _NACKSeqNum[kNackHistoryLength]; WebRtc_UWord32 _NACKSeqNumLength; + bool _waitingForKeyFrame; bool _firstPacket; };