This change basicly re-enables the change of r1220, which was reverted in r1235 due to Clang issues. The difference from r1220 is that the TickTimeInterface was renamed to TickTimeClass, and no longer inherits from TickTime. Review URL: http://webrtc-codereview.appspot.com/335006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1267 4adac7df-926f-26a2-2b94-8c16560cd09d
260 lines
10 KiB
C++
260 lines
10 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_JITTER_BUFFER_H_
|
|
#define WEBRTC_MODULES_VIDEO_CODING_JITTER_BUFFER_H_
|
|
|
|
#include "typedefs.h"
|
|
#include "critical_section_wrapper.h"
|
|
#include "decoding_state.h"
|
|
#include "module_common_types.h"
|
|
#include "video_coding_defines.h"
|
|
#include "inter_frame_delay.h"
|
|
#include "event.h"
|
|
#include "frame_list.h"
|
|
#include "jitter_buffer_common.h"
|
|
#include "jitter_estimator.h"
|
|
|
|
namespace webrtc
|
|
{
|
|
|
|
enum VCMNackMode
|
|
{
|
|
kNackInfinite,
|
|
kNackHybrid,
|
|
kNoNack
|
|
};
|
|
|
|
// forward declarations
|
|
class TickTimeBase;
|
|
class VCMFrameBuffer;
|
|
class VCMPacket;
|
|
class VCMEncodedFrame;
|
|
|
|
class VCMJitterSample
|
|
{
|
|
public:
|
|
VCMJitterSample() : timestamp(0), frameSize(0), latestPacketTime(-1) {}
|
|
WebRtc_UWord32 timestamp;
|
|
WebRtc_UWord32 frameSize;
|
|
WebRtc_Word64 latestPacketTime;
|
|
};
|
|
|
|
class VCMJitterBuffer
|
|
{
|
|
public:
|
|
VCMJitterBuffer(TickTimeBase* clock,
|
|
WebRtc_Word32 vcmId = -1,
|
|
WebRtc_Word32 receiverId = -1,
|
|
bool master = true);
|
|
virtual ~VCMJitterBuffer();
|
|
|
|
void CopyFrom(const VCMJitterBuffer& rhs);
|
|
|
|
// We need a start and stop to break out of the wait event
|
|
// used in GetCompleteFrameForDecoding
|
|
void Start();
|
|
void Stop();
|
|
bool Running() const;
|
|
|
|
// Empty the Jitter buffer of all its data
|
|
void Flush();
|
|
|
|
// Statistics, Get received key and delta frames
|
|
WebRtc_Word32 GetFrameStatistics(WebRtc_UWord32& receivedDeltaFrames,
|
|
WebRtc_UWord32& receivedKeyFrames) const;
|
|
|
|
// The number of packets discarded by the jitter buffer because the decoder
|
|
// won't be able to decode them.
|
|
WebRtc_UWord32 NumNotDecodablePackets() const;
|
|
// Get number of packets discarded by the jitter buffer
|
|
WebRtc_UWord32 DiscardedPackets() const;
|
|
|
|
// Statistics, Calculate frame and bit rates
|
|
WebRtc_Word32 GetUpdate(WebRtc_UWord32& frameRate, WebRtc_UWord32& bitRate);
|
|
|
|
// Wait for the first packet in the next frame to arrive, blocks
|
|
// for <= maxWaitTimeMS ms
|
|
WebRtc_Word64 GetNextTimeStamp(WebRtc_UWord32 maxWaitTimeMS,
|
|
FrameType& incomingFrameType,
|
|
WebRtc_Word64& renderTimeMs);
|
|
|
|
// Will the packet sequence be complete if the next frame is grabbed
|
|
// for decoding right now? That is, have we lost a frame between the
|
|
// last decoded frame and the next, or is the next frame missing one
|
|
// or more packets?
|
|
bool CompleteSequenceWithNextFrame();
|
|
|
|
// TODO (mikhal/stefan): Merge all GetFrameForDecoding into one.
|
|
// Wait maxWaitTimeMS for a complete frame to arrive. After timeout NULL
|
|
// is returned.
|
|
VCMEncodedFrame* GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS);
|
|
|
|
// Get a frame for decoding (even an incomplete) without delay.
|
|
VCMEncodedFrame* GetFrameForDecoding();
|
|
|
|
VCMEncodedFrame* GetFrameForDecodingNACK();
|
|
|
|
// Release frame (when done with decoding)
|
|
void ReleaseFrame(VCMEncodedFrame* frame);
|
|
|
|
// Get frame to use for this timestamp
|
|
WebRtc_Word32 GetFrame(const VCMPacket& packet, VCMEncodedFrame*&);
|
|
VCMEncodedFrame* GetFrame(const VCMPacket& packet); // deprecated
|
|
|
|
// Returns the time in ms when the latest packet was inserted into the frame.
|
|
// Retransmitted is set to true if any of the packets belonging to the frame
|
|
// has been retransmitted.
|
|
WebRtc_Word64 LastPacketTime(VCMEncodedFrame* frame,
|
|
bool& retransmitted) const;
|
|
|
|
// Insert a packet into a frame
|
|
VCMFrameBufferEnum InsertPacket(VCMEncodedFrame* frame,
|
|
const VCMPacket& packet);
|
|
|
|
// Sync
|
|
WebRtc_UWord32 GetEstimatedJitterMS();
|
|
void UpdateRtt(WebRtc_UWord32 rttMs);
|
|
|
|
// NACK
|
|
// Set the NACK mode. "highRttNackThreshold" is an RTT threshold in ms above
|
|
// which NACK will be disabled if the NACK mode is "kNackHybrid",
|
|
// -1 meaning that NACK is always enabled in the Hybrid mode.
|
|
// "lowRttNackThreshold" is an RTT threshold in ms below which we expect to
|
|
// rely on NACK only, and therefore are using larger buffers to have time to
|
|
// wait for retransmissions.
|
|
void SetNackMode(VCMNackMode mode,
|
|
int lowRttNackThresholdMs,
|
|
int highRttNackThresholdMs);
|
|
VCMNackMode GetNackMode() const; // Get nack mode
|
|
// Get list of missing sequence numbers (size in number of elements)
|
|
WebRtc_UWord16* GetNackList(WebRtc_UWord16& nackSize,
|
|
bool& listExtended);
|
|
|
|
WebRtc_Word64 LastDecodedTimestamp() const;
|
|
|
|
private:
|
|
// Misc help functions
|
|
// Recycle (release) frame, used if we didn't receive whole frame
|
|
void RecycleFrame(VCMFrameBuffer* frame);
|
|
void ReleaseFrameInternal(VCMFrameBuffer* frame);
|
|
// Flush and reset the jitter buffer. Call under critical section.
|
|
void FlushInternal();
|
|
|
|
// Help functions for insert packet
|
|
// Get empty frame, creates new (i.e. increases JB size) if necessary
|
|
VCMFrameBuffer* GetEmptyFrame();
|
|
// Recycle oldest frames up to a key frame, used if JB is completely full
|
|
bool RecycleFramesUntilKeyFrame();
|
|
// Update frame state
|
|
// (set as complete or reconstructable if conditions are met)
|
|
VCMFrameBufferEnum UpdateFrameState(VCMFrameBuffer* frameListItem);
|
|
|
|
// Help functions for getting a frame
|
|
// Find oldest complete frame, used for getting next frame to decode
|
|
// When enabled, will return a decodable frame
|
|
VCMFrameListItem* FindOldestCompleteContinuousFrame(bool enableDecodable);
|
|
|
|
void CleanUpOldFrames();
|
|
|
|
void VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame);
|
|
bool IsPacketRetransmitted(const VCMPacket& packet) const;
|
|
|
|
void UpdateJitterAndDelayEstimates(VCMJitterSample& sample,
|
|
bool incompleteFrame);
|
|
void UpdateJitterAndDelayEstimates(VCMFrameBuffer& frame,
|
|
bool incompleteFrame);
|
|
void UpdateJitterAndDelayEstimates(WebRtc_Word64 latestPacketTimeMs,
|
|
WebRtc_UWord32 timestamp,
|
|
WebRtc_UWord32 frameSize,
|
|
bool incompleteFrame);
|
|
void UpdateOldJitterSample(const VCMPacket& packet);
|
|
WebRtc_UWord32 GetEstimatedJitterMsInternal();
|
|
|
|
// NACK help
|
|
WebRtc_UWord16* CreateNackList(WebRtc_UWord16& nackSize,
|
|
bool& listExtended);
|
|
WebRtc_Word32 GetLowHighSequenceNumbers(WebRtc_Word32& lowSeqNum,
|
|
WebRtc_Word32& highSeqNum) const;
|
|
|
|
static bool FrameEqualTimestamp(VCMFrameBuffer* frame,
|
|
const void* timestamp);
|
|
static bool CompleteDecodableKeyFrameCriteria(VCMFrameBuffer* frame,
|
|
const void* notUsed);
|
|
// Decide whether should wait for NACK (mainly relevant for hybrid mode)
|
|
bool WaitForNack();
|
|
|
|
WebRtc_Word32 _vcmId;
|
|
WebRtc_Word32 _receiverId;
|
|
TickTimeBase* _clock;
|
|
// If we are running (have started) or not
|
|
bool _running;
|
|
CriticalSectionWrapper* _critSect;
|
|
bool _master;
|
|
// Event to signal when we have a frame ready for decoder
|
|
VCMEvent _frameEvent;
|
|
// Event to signal when we have received a packet
|
|
VCMEvent _packetEvent;
|
|
// Number of allocated frames
|
|
WebRtc_Word32 _maxNumberOfFrames;
|
|
// Array of pointers to the frames in JB
|
|
VCMFrameBuffer* _frameBuffers[kMaxNumberOfFrames];
|
|
VCMFrameListTimestampOrderAsc _frameBuffersTSOrder;
|
|
|
|
// timing
|
|
VCMDecodingState _lastDecodedState;
|
|
WebRtc_UWord32 _packetsNotDecodable;
|
|
|
|
// Statistics
|
|
// Frame counter for each type (key, delta, golden, key-delta)
|
|
WebRtc_UWord8 _receiveStatistics[4];
|
|
// Latest calculated frame rates of incoming stream
|
|
WebRtc_UWord8 _incomingFrameRate;
|
|
// Frame counter, reset in GetUpdate
|
|
WebRtc_UWord32 _incomingFrameCount;
|
|
// Real time for last _frameCount reset
|
|
WebRtc_Word64 _timeLastIncomingFrameCount;
|
|
// Received bits counter, reset in GetUpdate
|
|
WebRtc_UWord32 _incomingBitCount;
|
|
WebRtc_UWord32 _incomingBitRate;
|
|
WebRtc_UWord32 _dropCount; // Frame drop counter
|
|
// Number of frames in a row that have been too old
|
|
WebRtc_UWord32 _numConsecutiveOldFrames;
|
|
// Number of packets in a row that have been too old
|
|
WebRtc_UWord32 _numConsecutiveOldPackets;
|
|
// Number of packets discarded by the jitter buffer
|
|
WebRtc_UWord32 _discardedPackets;
|
|
|
|
// Filters for estimating jitter
|
|
VCMJitterEstimator _jitterEstimate;
|
|
// Calculates network delays used for jitter calculations
|
|
VCMInterFrameDelay _delayEstimate;
|
|
VCMJitterSample _waitingForCompletion;
|
|
WebRtc_UWord32 _rttMs;
|
|
|
|
// NACK
|
|
VCMNackMode _nackMode;
|
|
int _lowRttNackThresholdMs;
|
|
int _highRttNackThresholdMs;
|
|
// Holds the internal nack list (the missing sequence numbers)
|
|
WebRtc_Word32 _NACKSeqNumInternal[kNackHistoryLength];
|
|
WebRtc_UWord16 _NACKSeqNum[kNackHistoryLength];
|
|
WebRtc_UWord32 _NACKSeqNumLength;
|
|
bool _waitingForKeyFrame;
|
|
|
|
bool _firstPacket;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer);
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // WEBRTC_MODULES_VIDEO_CODING_JITTER_BUFFER_H_
|