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 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4104 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -32,8 +32,6 @@ enum VCMNackMode {
|
||||
kNoNack
|
||||
};
|
||||
|
||||
typedef std::list<VCMFrameBuffer*> FrameList;
|
||||
|
||||
// forward declarations
|
||||
class Clock;
|
||||
class EventFactory;
|
||||
@ -49,6 +47,15 @@ struct VCMJitterSample {
|
||||
int64_t latest_packet_time;
|
||||
};
|
||||
|
||||
class FrameList : public std::list<VCMFrameBuffer*> {
|
||||
public:
|
||||
void InsertFrame(VCMFrameBuffer* frame);
|
||||
VCMFrameBuffer* FindFrame(uint32_t timestamp) const;
|
||||
VCMFrameBuffer* PopFrame(uint32_t timestamp);
|
||||
int RecycleFramesUntilKeyFrame(FrameList::iterator* key_frame_it);
|
||||
int CleanUpOldOrEmptyFrames(VCMDecodingState* decoding_state);
|
||||
};
|
||||
|
||||
class VCMJitterBuffer {
|
||||
public:
|
||||
VCMJitterBuffer(Clock* clock,
|
||||
@ -120,6 +127,8 @@ class VCMJitterBuffer {
|
||||
bool* retransmitted) const;
|
||||
|
||||
// Inserts a packet into a frame returned from GetFrame().
|
||||
// If the return value is <= 0, |frame| is invalidated and the pointer must
|
||||
// be dropped after this function returns.
|
||||
VCMFrameBufferEnum InsertPacket(const VCMPacket& packet,
|
||||
bool* retransmitted);
|
||||
|
||||
@ -175,6 +184,18 @@ class VCMJitterBuffer {
|
||||
// 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 |frame| is continuous in |decoding_state|, not taking
|
||||
// decodable frames into account.
|
||||
bool IsContinuousInState(const VCMFrameBuffer& frame,
|
||||
const VCMDecodingState& decoding_state) const;
|
||||
// Returns true if |frame| is continuous in the |last_decoded_state_|, taking
|
||||
// all decodable frames into account.
|
||||
bool IsContinuous(const VCMFrameBuffer& frame) const;
|
||||
// Looks for frames in |incomplete_frames_| which are continuous in
|
||||
// |last_decoded_state_| taking all decodable frames into account. Starts
|
||||
// the search from |new_frame|.
|
||||
void FindAndInsertContinuousFrames(const VCMFrameBuffer& new_frame);
|
||||
VCMFrameBuffer* NextFrame() const;
|
||||
// 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.
|
||||
@ -202,19 +223,8 @@ class VCMJitterBuffer {
|
||||
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);
|
||||
// Also updates the frame statistics.
|
||||
void UpdateFrameState(VCMFrameBuffer* frame);
|
||||
|
||||
// Cleans the frame list in the JB from old/empty frames.
|
||||
// Should only be called prior to actual use.
|
||||
@ -263,7 +273,8 @@ class VCMJitterBuffer {
|
||||
int max_number_of_frames_;
|
||||
// Array of pointers to the frames in jitter buffer.
|
||||
VCMFrameBuffer* frame_buffers_[kMaxNumberOfFrames];
|
||||
FrameList frame_list_;
|
||||
FrameList decodable_frames_;
|
||||
FrameList incomplete_frames_;
|
||||
VCMDecodingState last_decoded_state_;
|
||||
bool first_packet_since_reset_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user