Making dual decoder work again in VCM

Changing the assignment operator in VCMJitterBuffer to a named
function (CopyFrom) instead, since it is not a straight
assignment. Also fixing two bugs in the jitter copy function.

Bug fix in VCMEncodedFrame: The copy constructor did not
copy _length.

In VCM codec database, make sure that the callback object is
preserved when copying back from secondary to primary decoder.

In VP8 wrapper, adding code to copy the _decodedImage to the
Copy() method.

Bugfix in video_coding_test rtp_player:
The retransmissions where made in reverse order. Now new items are
appended to the end of the LostPackets list, which makes the order
correct when retransmitting.

Handling the case when cloning an unused decoder state:
When the decoder has not successfully decoded a frame yet,
it cannot be cloned. A NULL pointer will be returned all
the way out to VideoCodingModuleImpl::Decode(). When this
happens, the VCM will call Reset() for the dual receiver,
in order to reset the state to kPassive.

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@873 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org 2011-11-02 18:58:39 +00:00
parent 4bb141078f
commit baf6db5ead
9 changed files with 48 additions and 12 deletions

View File

@ -1162,13 +1162,11 @@ VP8Decoder::Copy()
if (_decodedImage._buffer == NULL)
{
// Nothing has been decoded before; cannot clone.
assert(false);
return NULL;
}
if (_lastKeyFrame._buffer == NULL)
{
// Cannot clone if we have no key frame to start with.
assert(false);
return NULL;
}
@ -1242,6 +1240,14 @@ VP8Decoder::Copy()
memcpy(copyTo->_lastKeyFrame._buffer, _lastKeyFrame._buffer,
_lastKeyFrame._length);
// Initialize _decodedImage.
copyTo->_decodedImage = _decodedImage; // Shallow copy
copyTo->_decodedImage._buffer = NULL;
if (_decodedImage._size)
{
copyTo->_decodedImage._buffer = new WebRtc_UWord8[_decodedImage._size];
}
return static_cast<VideoDecoder*>(copyTo);
}

View File

@ -9,6 +9,9 @@
*/
#include "codec_database.h"
#include <assert.h>
#include "../../../../engine_configurations.h"
#include "internal_defines.h"
#include "trace.h"
@ -694,8 +697,15 @@ VCMCodecDataBase::CopyDecoder(const VCMGenericDecoder& decoder)
VideoDecoder* decoderCopy = decoder._decoder.Copy();
if (decoderCopy != NULL)
{
VCMDecodedFrameCallback* cb = _ptrDecoder->_callback;
ReleaseDecoder(_ptrDecoder);
_ptrDecoder = new VCMGenericDecoder(*decoderCopy, _id, decoder.External());
_ptrDecoder = new VCMGenericDecoder(*decoderCopy, _id,
decoder.External());
if (cb)
{
WebRtc_Word32 ret = _ptrDecoder->RegisterDecodeCompleteCallback(cb);
assert(ret == WEBRTC_VIDEO_CODEC_OK);
}
}
}

View File

@ -63,6 +63,7 @@ VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
{
VerifyAndAllocate(rhs._size);
memcpy(_buffer, rhs._buffer, rhs._length);
_length = rhs._length;
}
// Deep operator=
_fragmentation = rhs._fragmentation;

View File

@ -115,8 +115,8 @@ VCMJitterBuffer::~VCMJitterBuffer()
delete &_critSect;
}
VCMJitterBuffer&
VCMJitterBuffer::operator=(const VCMJitterBuffer& rhs)
void
VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs)
{
if (this != &rhs)
{
@ -138,7 +138,6 @@ VCMJitterBuffer::operator=(const VCMJitterBuffer& rhs)
_jitterEstimate = rhs._jitterEstimate;
_delayEstimate = rhs._delayEstimate;
_waitingForCompletion = rhs._waitingForCompletion;
_nackMode = rhs._nackMode;
_rttMs = rhs._rttMs;
_NACKSeqNumLength = rhs._NACKSeqNumLength;
_waitingForKeyFrame = rhs._waitingForKeyFrame;
@ -173,7 +172,6 @@ VCMJitterBuffer::operator=(const VCMJitterBuffer& rhs)
rhs._critSect.Leave();
_critSect.Leave();
}
return *this;
}
// Start jitter buffer
@ -971,6 +969,10 @@ VCMJitterBuffer::CompleteSequenceWithNextFrame()
// Frame not ready to be decoded.
return true;
}
if (!oldestFrame->Complete())
{
return false;
}
// See if we have lost a frame before this one.
if (_lastDecodedSeqNum == -1)

View File

@ -53,7 +53,7 @@ public:
bool master = true);
virtual ~VCMJitterBuffer();
VCMJitterBuffer& operator=(const VCMJitterBuffer& rhs);
void CopyFrom(const VCMJitterBuffer& rhs);
// We need a start and stop to break out of the wait event
// used in GetCompleteFrameForDecoding
@ -241,6 +241,8 @@ private:
bool _waitingForKeyFrame;
bool _firstPacket;
DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer);
};
} // namespace webrtc

View File

@ -42,8 +42,8 @@ VCMReceiver::~VCMReceiver()
delete &_critSect;
}
WebRtc_Word32
VCMReceiver::Initialize()
void
VCMReceiver::Reset()
{
CriticalSectionScoped cs(_critSect);
if (!_jitterBuffer.Running())
@ -62,6 +62,16 @@ VCMReceiver::Initialize()
else
{
_state = kPassive;
}
}
WebRtc_Word32
VCMReceiver::Initialize()
{
CriticalSectionScoped cs(_critSect);
Reset();
if (!_master)
{
SetNackMode(kNoNack);
}
return VCM_OK;
@ -416,7 +426,7 @@ VCMReceiver::DualDecoderCaughtUp(VCMEncodedFrame* dualFrame, VCMReceiver& dualRe
void
VCMReceiver::CopyJitterBufferStateFromReceiver(const VCMReceiver& receiver)
{
_jitterBuffer = receiver._jitterBuffer;
_jitterBuffer.CopyFrom(receiver._jitterBuffer);
}
VCMReceiverState

View File

@ -45,6 +45,7 @@ public:
bool master = true);
~VCMReceiver();
void Reset();
WebRtc_Word32 Initialize();
void UpdateRtt(WebRtc_UWord32 rtt);
WebRtc_Word32 InsertPacket(const VCMPacket& packet,

View File

@ -1071,6 +1071,10 @@ VideoCodingModuleImpl::Decode(WebRtc_UWord16 maxWaitTimeMs)
_dualDecoder->RegisterDecodeCompleteCallback(
&_dualDecodedFrameCallback);
}
else
{
_dualReceiver.Reset();
}
}
if (frame == NULL)

View File

@ -70,7 +70,7 @@ WebRtc_UWord32 LostPackets::AddPacket(WebRtc_UWord8* rtpData, WebRtc_UWord16 rtp
CriticalSectionScoped cs(_critSect);
RawRtpPacket* packet = new RawRtpPacket(rtpData, rtpLen);
ListItem* newItem = new ListItem(packet);
InsertBefore(First(), newItem);
Insert(Last(), newItem);
const WebRtc_UWord16 seqNo = (rtpData[2] << 8) + rtpData[3];
if (_debugFile != NULL)
{