
relanding 1323006 BUG= Review URL: https://webrtc-codereview.appspot.com/1354004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3902 4adac7df-926f-26a2-2b94-8c16560cd09d
302 lines
12 KiB
C++
302 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2012 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_MAIN_SOURCE_JITTER_BUFFER_H_
|
|
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_JITTER_BUFFER_H_
|
|
|
|
#include <list>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#include "webrtc/modules/interface/module_common_types.h"
|
|
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
|
|
#include "webrtc/modules/video_coding/main/source/decoding_state.h"
|
|
#include "webrtc/modules/video_coding/main/source/inter_frame_delay.h"
|
|
#include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
|
|
#include "webrtc/modules/video_coding/main/source/jitter_estimator.h"
|
|
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
|
#include "webrtc/typedefs.h"
|
|
|
|
namespace webrtc {
|
|
|
|
enum VCMNackMode {
|
|
kNack,
|
|
kNoNack
|
|
};
|
|
|
|
typedef std::list<VCMFrameBuffer*> FrameList;
|
|
|
|
// forward declarations
|
|
class Clock;
|
|
class EventFactory;
|
|
class EventWrapper;
|
|
class VCMFrameBuffer;
|
|
class VCMPacket;
|
|
class VCMEncodedFrame;
|
|
|
|
struct VCMJitterSample {
|
|
VCMJitterSample() : timestamp(0), frame_size(0), latest_packet_time(-1) {}
|
|
uint32_t timestamp;
|
|
uint32_t frame_size;
|
|
int64_t latest_packet_time;
|
|
};
|
|
|
|
class VCMJitterBuffer {
|
|
public:
|
|
VCMJitterBuffer(Clock* clock,
|
|
EventFactory* event_factory,
|
|
int vcm_id,
|
|
int receiver_id,
|
|
bool master);
|
|
virtual ~VCMJitterBuffer();
|
|
|
|
// Makes |this| a deep copy of |rhs|.
|
|
void CopyFrom(const VCMJitterBuffer& rhs);
|
|
|
|
// Initializes and starts jitter buffer.
|
|
void Start();
|
|
|
|
// Signals all internal events and stops the jitter buffer.
|
|
void Stop();
|
|
|
|
// Returns true if the jitter buffer is running.
|
|
bool Running() const;
|
|
|
|
// Empty the jitter buffer of all its data.
|
|
void Flush();
|
|
|
|
// Get the number of received key and delta frames since the jitter buffer
|
|
// was started.
|
|
void FrameStatistics(uint32_t* received_delta_frames,
|
|
uint32_t* received_key_frames) const;
|
|
|
|
// The number of packets discarded by the jitter buffer because the decoder
|
|
// won't be able to decode them.
|
|
int num_not_decodable_packets() const;
|
|
|
|
// Gets number of packets discarded by the jitter buffer.
|
|
int num_discarded_packets() const;
|
|
|
|
// Statistics, Calculate frame and bit rates.
|
|
void IncomingRateStatistics(unsigned int* framerate,
|
|
unsigned int* bitrate);
|
|
|
|
// Waits for the first packet in the next frame to arrive and then returns
|
|
// the timestamp of that frame. |incoming_frame_type| and |render_time_ms| are
|
|
// set to the frame type and render time of the next frame.
|
|
// Blocks for up to |max_wait_time_ms| ms. Returns -1 if no packet has arrived
|
|
// after |max_wait_time_ms| ms.
|
|
int64_t NextTimestamp(uint32_t max_wait_time_ms,
|
|
FrameType* incoming_frame_type,
|
|
int64_t* render_time_ms);
|
|
|
|
// Checks if the packet sequence will be complete if the next frame would be
|
|
// grabbed for decoding. That is, if a frame has been lost between the
|
|
// last decoded frame and the next, or if the next frame is missing one
|
|
// or more packets.
|
|
bool CompleteSequenceWithNextFrame();
|
|
|
|
// Returns a complete frame ready for decoding. Allows max_wait_time_ms to
|
|
// wait for such a frame, if one is unavailable.
|
|
// Always starts with a key frame.
|
|
VCMEncodedFrame* GetCompleteFrameForDecoding(uint32_t max_wait_time_ms);
|
|
|
|
// Get next frame for decoding without delay. If decoding with errors is not
|
|
// enabled, will return NULL. Actual returned frame will be the next one in
|
|
// the list, either complete or not.
|
|
// TODO(mikhal): Consider only allowing decodable/complete.
|
|
VCMEncodedFrame* MaybeGetIncompleteFrameForDecoding();
|
|
|
|
// Releases a frame returned from the jitter buffer, should be called when
|
|
// done with decoding.
|
|
void ReleaseFrame(VCMEncodedFrame* frame);
|
|
|
|
// Returns the frame assigned to this timestamp.
|
|
int 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.
|
|
int64_t LastPacketTime(VCMEncodedFrame* frame, bool* retransmitted) const;
|
|
|
|
// Inserts a packet into a frame returned from GetFrame().
|
|
VCMFrameBufferEnum InsertPacket(VCMEncodedFrame* frame,
|
|
const VCMPacket& packet);
|
|
|
|
// Enable a max filter on the jitter estimate by setting an initial
|
|
// non-zero delay. When set to zero (default), the last jitter
|
|
// estimate will be used.
|
|
void SetMaxJitterEstimate(uint32_t initial_delay_ms);
|
|
|
|
// Returns the estimated jitter in milliseconds.
|
|
uint32_t EstimatedJitterMs();
|
|
|
|
// Updates the round-trip time estimate.
|
|
void UpdateRtt(uint32_t rtt_ms);
|
|
|
|
// 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 low_rtt_nack_threshold_ms,
|
|
int high_rtt_nack_threshold_ms);
|
|
|
|
void SetNackSettings(size_t max_nack_list_size,
|
|
int max_packet_age_to_nack);
|
|
|
|
// Returns the current NACK mode.
|
|
VCMNackMode nack_mode() const;
|
|
|
|
// Returns a list of the sequence numbers currently missing.
|
|
uint16_t* GetNackList(uint16_t* nack_list_size, bool* request_key_frame);
|
|
|
|
// Enable/disable decoding with errors.
|
|
void DecodeWithErrors(bool enable) {decode_with_errors_ = enable;}
|
|
int64_t LastDecodedTimestamp() const;
|
|
bool decode_with_errors() const {return decode_with_errors_;}
|
|
|
|
private:
|
|
class SequenceNumberLessThan {
|
|
public:
|
|
bool operator() (const uint16_t& sequence_number1,
|
|
const uint16_t& sequence_number2) const {
|
|
return IsNewerSequenceNumber(sequence_number2, sequence_number1);
|
|
}
|
|
};
|
|
typedef std::set<uint16_t, SequenceNumberLessThan> SequenceNumberSet;
|
|
|
|
// Returns true if the NACK list was updated to cover sequence numbers up to
|
|
// |sequence_number|. If false a key frame is needed to get into a state where
|
|
// we can continue decoding.
|
|
bool UpdateNackList(uint16_t sequence_number);
|
|
bool TooLargeNackList() const;
|
|
// Returns true if the NACK list was reduced without problem. If false a key
|
|
// frame is needed to get into a state where we can continue decoding.
|
|
bool HandleTooLargeNackList();
|
|
bool MissingTooOldPacket(uint16_t latest_sequence_number) const;
|
|
// Returns true if the too old packets was successfully removed from the NACK
|
|
// list. If false, a key frame is needed to get into a state where we can
|
|
// continue decoding.
|
|
bool HandleTooOldPackets(uint16_t latest_sequence_number);
|
|
// Drops all packets in the NACK list up until |last_decoded_sequence_number|.
|
|
void DropPacketsFromNackList(uint16_t last_decoded_sequence_number);
|
|
|
|
void ReleaseFrameIfNotDecoding(VCMFrameBuffer* frame);
|
|
|
|
// Gets an empty frame, creating a new frame if necessary (i.e. increases
|
|
// jitter buffer size).
|
|
VCMFrameBuffer* GetEmptyFrame();
|
|
|
|
// Recycles oldest frames until a key frame is found. Used if jitter buffer is
|
|
// completely full. Returns true if a key frame was found.
|
|
bool RecycleFramesUntilKeyFrame();
|
|
|
|
// Sets the state of |frame| to complete if it's not too old to be decoded.
|
|
// Also updates the frame statistics. Signals the |frame_event| if this is
|
|
// the next frame to be decoded.
|
|
VCMFrameBufferEnum UpdateFrameState(VCMFrameBuffer* frame);
|
|
|
|
// Finds the oldest complete frame, used for getting next frame to decode.
|
|
// Can return a decodable, incomplete frame when enabled.
|
|
FrameList::iterator FindOldestCompleteContinuousFrame();
|
|
|
|
void CleanUpOldOrEmptyFrames();
|
|
|
|
// Sets the "decodable" and "frame loss" flags of a frame depending on which
|
|
// packets have been received and which are missing.
|
|
// A frame is "decodable" if enough packets of that frame has been received
|
|
// for it to be usable by the decoder.
|
|
// A frame has the "frame loss" flag set if packets are missing after the
|
|
// last decoded frame and before |frame|.
|
|
void VerifyAndSetPreviousFrameLost(VCMFrameBuffer* frame);
|
|
|
|
// Returns true if |packet| is likely to have been retransmitted.
|
|
bool IsPacketRetransmitted(const VCMPacket& packet) const;
|
|
|
|
// The following three functions update the jitter estimate with the
|
|
// payload size, receive time and RTP timestamp of a frame.
|
|
void UpdateJitterEstimate(const VCMJitterSample& sample,
|
|
bool incomplete_frame);
|
|
void UpdateJitterEstimate(const VCMFrameBuffer& frame, bool incomplete_frame);
|
|
void UpdateJitterEstimate(int64_t latest_packet_time_ms,
|
|
uint32_t timestamp,
|
|
unsigned int frame_size,
|
|
bool incomplete_frame);
|
|
|
|
// Returns true if we should wait for retransmissions, false otherwise.
|
|
bool WaitForRetransmissions();
|
|
|
|
int vcm_id_;
|
|
int receiver_id_;
|
|
Clock* clock_;
|
|
// If we are running (have started) or not.
|
|
bool running_;
|
|
CriticalSectionWrapper* crit_sect_;
|
|
bool master_;
|
|
// Event to signal when we have a frame ready for decoder.
|
|
scoped_ptr<EventWrapper> frame_event_;
|
|
// Event to signal when we have received a packet.
|
|
scoped_ptr<EventWrapper> packet_event_;
|
|
// Number of allocated frames.
|
|
int max_number_of_frames_;
|
|
// Array of pointers to the frames in jitter buffer.
|
|
VCMFrameBuffer* frame_buffers_[kMaxNumberOfFrames];
|
|
FrameList frame_list_;
|
|
VCMDecodingState last_decoded_state_;
|
|
bool first_packet_;
|
|
|
|
// Statistics.
|
|
int num_not_decodable_packets_;
|
|
// Frame counter for each type (key, delta, golden, key-delta).
|
|
unsigned int receive_statistics_[4];
|
|
// Latest calculated frame rates of incoming stream.
|
|
unsigned int incoming_frame_rate_;
|
|
unsigned int incoming_frame_count_;
|
|
int64_t time_last_incoming_frame_count_;
|
|
unsigned int incoming_bit_count_;
|
|
unsigned int incoming_bit_rate_;
|
|
unsigned int drop_count_; // Frame drop counter.
|
|
// Number of frames in a row that have been too old.
|
|
int num_consecutive_old_frames_;
|
|
// Number of packets in a row that have been too old.
|
|
int num_consecutive_old_packets_;
|
|
// Number of packets discarded by the jitter buffer.
|
|
int num_discarded_packets_;
|
|
|
|
// Jitter estimation.
|
|
// Filter for estimating jitter.
|
|
VCMJitterEstimator jitter_estimate_;
|
|
// Calculates network delays used for jitter calculations.
|
|
VCMInterFrameDelay inter_frame_delay_;
|
|
VCMJitterSample waiting_for_completion_;
|
|
uint32_t rtt_ms_;
|
|
|
|
// NACK and retransmissions.
|
|
VCMNackMode nack_mode_;
|
|
int low_rtt_nack_threshold_ms_;
|
|
int high_rtt_nack_threshold_ms_;
|
|
// Holds the internal NACK list (the missing sequence numbers).
|
|
SequenceNumberSet missing_sequence_numbers_;
|
|
uint16_t latest_received_sequence_number_;
|
|
std::vector<uint16_t> nack_seq_nums_;
|
|
size_t max_nack_list_size_;
|
|
int max_packet_age_to_nack_; // Measured in sequence numbers.
|
|
|
|
bool decode_with_errors_;
|
|
DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer);
|
|
};
|
|
} // namespace webrtc
|
|
|
|
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_JITTER_BUFFER_H_
|