Files
platform-external-webrtc/webrtc/modules/video_coding/main/source/jitter_buffer.h
tnakamura@webrtc.org 694cdc6e84 Revert 4104 "Refactor jitter buffer to use separate lists for de..."
Reason - leading suspect of video frame corruption tracked in http://b/9216252
Note that if this turns out to not be the cause, be sure to re-revert both this change and r4145.

> Refactor jitter buffer to use separate lists for decodable and incomplete frames.
> 
> This changes the design of the jitter buffer to keeping track of decodable frames from the point when packets are inserted in the buffer, instead of searching for decodable frames when they are needed.
> 
> To accomplish this the frame_list_, which previously contained all frames (incomplete or complete, continuous or not), is split into a list of decodable_frames_ (complete, continuous) and a list of incomplete_frames_ (either incomplete or non-continuous). These frame lists are updated every time a packet is inserted.
> 
> This is another step in the direction of doing most of the work in the jitter buffer only once, when packets are inserted, instead of doing it every time we look for a frame or try to get a nack list.
> 
> BUG=1798
> TEST=vie_auto_test, trybots
> R=mikhal@webrtc.org
> 
> Review URL: https://webrtc-codereview.appspot.com/1522005

TBR=stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1586007

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4146 4adac7df-926f-26a2-2b94-8c16560cd09d
2013-05-31 16:09:48 +00:00

314 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);
// 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();
// Wait |max_wait_time_ms| for a complete frame to arrive.
// The function returns true once such a frame is found, its corresponding
// timestamp is returned. Otherwise, returns false.
bool NextCompleteTimestamp(uint32_t max_wait_time_ms, uint32_t* timestamp);
// Locates a frame for decoding (even an incomplete) without delay.
// The function returns true once such a frame is found, its corresponding
// timestamp is returned. Otherwise, returns false.
bool NextMaybeIncompleteTimestamp(uint32_t* timestamp);
// Extract frame corresponding to input timestamp.
// Frame will be set to a decoding state.
VCMEncodedFrame* ExtractAndSetDecode(uint32_t timestamp);
// Releases a frame returned from the jitter buffer, should be called when
// done with decoding.
void ReleaseFrame(VCMEncodedFrame* frame);
// 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(const VCMEncodedFrame* frame,
bool* retransmitted) const;
// Inserts a packet into a frame returned from GetFrame().
VCMFrameBufferEnum InsertPacket(const VCMPacket& packet,
bool* retransmitted);
// Enable a max filter on the jitter estimate by setting an initial
// non-zero delay.
void SetMaxJitterEstimate(bool enable);
// 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,
int max_incomplete_time_ms);
// 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_;}
// Used to compute time of complete continuous frames. Returns the timestamps
// corresponding to the start and end of the continuous complete buffer.
void RenderBufferSize(uint32_t* timestamp_start, uint32_t* timestamp_end);
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;
// Gets the frame assigned to the timestamp of the packet. May recycle
// existing frames if no free frames are available. Returns an error code if
// failing, or kNoError on success.
VCMFrameBufferEnum GetFrame(const VCMPacket& packet, VCMFrameBuffer** frame);
// 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(
FrameList::iterator start_it,
const VCMDecodingState* decoding_state);
FrameList::iterator FindLastContinuousAndComplete(
FrameList::iterator start_it);
void RenderBuffer(FrameList::iterator* start_it,
FrameList::iterator* end_it);
// Cleans the frame list in the JB from old/empty frames.
// Should only be called prior to actual use.
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 NonContinuousOrIncompleteDuration();
uint16_t EstimatedLowSequenceNumber(const VCMFrameBuffer& frame) const;
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_since_reset_;
// 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.
int max_incomplete_time_ms_;
bool decode_with_errors_;
DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_JITTER_BUFFER_H_