henrik.lundin@webrtc.org baf6db5ead 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
2011-11-02 18:58:39 +00:00

99 lines
3.2 KiB
C++

/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_RECEIVER_H_
#define WEBRTC_MODULES_VIDEO_CODING_RECEIVER_H_
#include "critical_section_wrapper.h"
#include "jitter_buffer.h"
#include "timing.h"
#include "packet.h"
namespace webrtc
{
class VCMEncodedFrame;
enum VCMNackStatus
{
kNackOk,
kNackNeedMoreMemory,
kNackKeyFrameRequest
};
enum VCMReceiverState
{
kReceiving,
kPassive,
kWaitForPrimaryDecode
};
class VCMReceiver
{
public:
VCMReceiver(VCMTiming& timing,
WebRtc_Word32 vcmId = -1,
WebRtc_Word32 receiverId = -1,
bool master = true);
~VCMReceiver();
void Reset();
WebRtc_Word32 Initialize();
void UpdateRtt(WebRtc_UWord32 rtt);
WebRtc_Word32 InsertPacket(const VCMPacket& packet,
WebRtc_UWord16 frameWidth,
WebRtc_UWord16 frameHeight);
VCMEncodedFrame* FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs,
WebRtc_Word64& nextRenderTimeMs,
bool renderTiming = true,
VCMReceiver* dualReceiver = NULL);
void ReleaseFrame(VCMEncodedFrame* frame);
WebRtc_Word32 ReceiveStatistics(WebRtc_UWord32& bitRate, WebRtc_UWord32& frameRate);
WebRtc_Word32 ReceivedFrameCount(VCMFrameCount& frameCount) const;
WebRtc_UWord32 DiscardedPackets() const;
// NACK
void SetNackMode(VCMNackMode nackMode);
VCMNackMode NackMode() const;
VCMNackStatus NackList(WebRtc_UWord16* nackList, WebRtc_UWord16& size);
// Dual decoder
bool DualDecoderCaughtUp(VCMEncodedFrame* dualFrame, VCMReceiver& dualReceiver) const;
VCMReceiverState State() const;
private:
VCMEncodedFrame* FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs,
WebRtc_Word64 nextrenderTimeMs,
VCMReceiver* dualReceiver);
VCMEncodedFrame* FrameForRendering(WebRtc_UWord16 maxWaitTimeMs,
WebRtc_Word64 nextrenderTimeMs,
VCMReceiver* dualReceiver);
void CopyJitterBufferStateFromReceiver(const VCMReceiver& receiver);
void UpdateState(VCMReceiverState newState);
void UpdateState(VCMEncodedFrame& frame);
static WebRtc_Word32 GenerateReceiverId();
CriticalSectionWrapper& _critSect;
WebRtc_Word32 _vcmId;
WebRtc_Word32 _receiverId;
bool _master;
VCMJitterBuffer _jitterBuffer;
VCMTiming& _timing;
VCMEvent& _renderWaitEvent;
VCMReceiverState _state;
static WebRtc_Word32 _receiverIdCounter;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_RECEIVER_H_