Refactor NACK list creation to build the NACK list as packets arrive.
Also fixes a timer bug related to NACKing in the RTP module which could cause packets to only be NACKed twice if there's frequent packet losses. Note that I decided to remove any selective NACKing for now as I don't think the gain of doing it is big enough compared to the added complexity. The same reasoning for empty packets. None of them will be retransmitted by a smart sender since the sender would know that they aren't needed. BUG=1420 TEST=video_coding_unittests, vie_auto_test, video_coding_integrationtests, trybots Review URL: https://webrtc-codereview.appspot.com/1115006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3599 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -12,6 +12,7 @@
|
||||
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_JITTER_BUFFER_H_
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
@ -28,7 +29,9 @@
|
||||
namespace webrtc {
|
||||
|
||||
enum VCMNackMode {
|
||||
kNackInfinite,
|
||||
kNack,
|
||||
// TODO(holmer): There is no longer a hybrid NACK mode. We should remove this
|
||||
// and replace it with a jitter buffer API for setting allowing decode errors.
|
||||
kNackHybrid,
|
||||
kNoNack
|
||||
};
|
||||
@ -153,12 +156,40 @@ class VCMJitterBuffer {
|
||||
// Returns the current NACK mode.
|
||||
VCMNackMode nack_mode() const;
|
||||
|
||||
// Creates a list of missing sequence numbers.
|
||||
uint16_t* CreateNackList(uint16_t* nack_list_size, bool* list_extended);
|
||||
// Returns a list of the sequence numbers currently missing.
|
||||
uint16_t* GetNackList(uint16_t* nack_list_size, bool* request_key_frame);
|
||||
|
||||
int64_t LastDecodedTimestamp() const;
|
||||
|
||||
private:
|
||||
class SequenceNumberLessThan {
|
||||
public:
|
||||
bool operator() (const uint16_t& sequence_number1,
|
||||
const uint16_t& sequence_number2) const {
|
||||
if (sequence_number1 == sequence_number2)
|
||||
return false;
|
||||
return LatestSequenceNumber(sequence_number1, sequence_number2, NULL) ==
|
||||
sequence_number2;
|
||||
}
|
||||
};
|
||||
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);
|
||||
|
||||
// In NACK-only mode this function doesn't return or release non-complete
|
||||
// frames unless we have a complete key frame. In hybrid mode, we may release
|
||||
// "decodable", incomplete frames.
|
||||
@ -183,7 +214,7 @@ class VCMJitterBuffer {
|
||||
// Can return a decodable, incomplete frame if |enable_decodable| is true.
|
||||
FrameList::iterator FindOldestCompleteContinuousFrame(bool enable_decodable);
|
||||
|
||||
void CleanUpOldFrames();
|
||||
void CleanUpOldOrEmptyFrames();
|
||||
|
||||
// Sets the "decodable" and "frame loss" flags of a frame depending on which
|
||||
// packets have been received and which are missing.
|
||||
@ -206,12 +237,6 @@ class VCMJitterBuffer {
|
||||
unsigned int frame_size,
|
||||
bool incomplete_frame);
|
||||
|
||||
// Returns the lowest and highest known sequence numbers, where the lowest is
|
||||
// the last decoded sequence number if a frame has been decoded.
|
||||
// -1 is returned if a sequence number cannot be determined.
|
||||
void GetLowHighSequenceNumbers(int32_t* low_seq_num,
|
||||
int32_t* high_seq_num) const;
|
||||
|
||||
// Returns true if we should wait for retransmissions, false otherwise.
|
||||
bool WaitForRetransmissions();
|
||||
|
||||
@ -265,9 +290,9 @@ class VCMJitterBuffer {
|
||||
int low_rtt_nack_threshold_ms_;
|
||||
int high_rtt_nack_threshold_ms_;
|
||||
// Holds the internal NACK list (the missing sequence numbers).
|
||||
std::vector<int> nack_seq_nums_internal_;
|
||||
SequenceNumberSet missing_sequence_numbers_;
|
||||
uint16_t latest_received_sequence_number_;
|
||||
std::vector<uint16_t> nack_seq_nums_;
|
||||
unsigned int nack_seq_nums_length_;
|
||||
size_t max_nack_list_size_;
|
||||
int max_packet_age_to_nack_; // Measured in sequence numbers.
|
||||
bool waiting_for_key_frame_;
|
||||
|
||||
Reference in New Issue
Block a user