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:
parent
4bb141078f
commit
baf6db5ead
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -1071,6 +1071,10 @@ VideoCodingModuleImpl::Decode(WebRtc_UWord16 maxWaitTimeMs)
|
||||
_dualDecoder->RegisterDecodeCompleteCallback(
|
||||
&_dualDecodedFrameCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dualReceiver.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (frame == NULL)
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user