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:
@ -82,11 +82,21 @@ void VCMDecodingState::CopyFrom(const VCMDecodingState& state) {
|
||||
in_initial_state_ = state.in_initial_state_;
|
||||
}
|
||||
|
||||
void VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) {
|
||||
if (ContinuousFrame(frame)) {
|
||||
time_stamp_ = frame->TimeStamp();
|
||||
sequence_num_ = frame->GetHighSeqNum();
|
||||
bool VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) {
|
||||
bool empty_packet = frame->GetHighSeqNum() == frame->GetLowSeqNum();
|
||||
if (in_initial_state_ && empty_packet) {
|
||||
// Drop empty packets as long as we are in the initial state.
|
||||
return true;
|
||||
}
|
||||
if ((empty_packet && ContinuousSeqNum(frame->GetHighSeqNum())) ||
|
||||
ContinuousFrame(frame)) {
|
||||
// Continuous empty packets or continuous frames can be dropped if we
|
||||
// advance the sequence number.
|
||||
sequence_num_ = frame->GetHighSeqNum();
|
||||
time_stamp_ = frame->TimeStamp();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void VCMDecodingState::UpdateOldPacket(const VCMPacket* packet) {
|
||||
@ -139,11 +149,14 @@ bool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const {
|
||||
// Return true when in initial state.
|
||||
// Note that when a method is not applicable it will return false.
|
||||
assert(frame != NULL);
|
||||
if (in_initial_state_) {
|
||||
// Always start with a key frame.
|
||||
if (frame->FrameType() == kVideoFrameKey) return true;
|
||||
// A key frame is always considered continuous as it doesn't refer to any
|
||||
// frames and therefore won't introduce any errors even if prior frames are
|
||||
// missing.
|
||||
if (frame->FrameType() == kVideoFrameKey)
|
||||
return true;
|
||||
// When in the initial state we always require a key frame to start decoding.
|
||||
if (in_initial_state_)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) {
|
||||
// Base layers are not continuous or temporal layers are inactive.
|
||||
|
Reference in New Issue
Block a user