video_coding/jitter_buffer: Account for layer info when searching for the next frame
Review URL: http://webrtc-codereview.appspot.com/328003 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1256 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -538,46 +538,51 @@ VCMJitterBuffer::GetEmptyFrame()
|
|||||||
|
|
||||||
// Find oldest complete frame used for getting next frame to decode
|
// Find oldest complete frame used for getting next frame to decode
|
||||||
// Must be called under critical section
|
// Must be called under critical section
|
||||||
// Based on sequence number
|
|
||||||
// Return NULL for lost packets
|
|
||||||
VCMFrameListItem*
|
VCMFrameListItem*
|
||||||
VCMJitterBuffer::FindOldestCompleteContinuousFrame(bool enableDecodable) {
|
VCMJitterBuffer::FindOldestCompleteContinuousFrame(bool enable_decodable) {
|
||||||
// If we have more than one frame done since last time, pick oldest.
|
// If we have more than one frame done since last time, pick oldest.
|
||||||
VCMFrameBuffer* oldestFrame = NULL;
|
VCMFrameListItem* oldest_frame_item = _frameBuffersTSOrder.First();
|
||||||
|
VCMFrameBuffer* oldest_frame = NULL;
|
||||||
|
|
||||||
VCMFrameListItem* oldestFrameItem = _frameBuffersTSOrder.First();
|
// When temporal layers are available, we search for a complete or decodable
|
||||||
if (oldestFrameItem != NULL) {
|
// frame until we hit one of the following:
|
||||||
oldestFrame = oldestFrameItem->GetItem();
|
// 1. Continuous base or sync layer.
|
||||||
}
|
// 2. The end of the list was reached.
|
||||||
if (oldestFrame != NULL) {
|
while (oldest_frame_item != NULL) {
|
||||||
// Check for a complete or decodable frame (when enabled).
|
oldest_frame = oldest_frame_item->GetItem();
|
||||||
VCMFrameBufferStateEnum state = oldestFrame->GetState();
|
if (oldest_frame) {
|
||||||
bool decodable = enableDecodable && (state == kStateDecodable);
|
VCMFrameBufferStateEnum state = oldest_frame->GetState();
|
||||||
if ((state != kStateComplete) && !decodable) {
|
// Is this frame complete or decodable and continuous?
|
||||||
oldestFrame = NULL;
|
if ((state == kStateComplete ||
|
||||||
|
(enable_decodable && state == kStateDecodable)) &&
|
||||||
|
_lastDecodedState.ContinuousFrame(oldest_frame)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
int temporal_id = oldest_frame->TemporalId();
|
||||||
|
oldest_frame = NULL;
|
||||||
|
if (temporal_id <= 0) {
|
||||||
|
// When temporal layers are disabled or we have hit a base layer
|
||||||
|
// we break (regardless of continuity and completeness).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Temporal layers are available, and we have yet to reach a base layer
|
||||||
|
// frame (complete/decodable or not) => Read next frame.
|
||||||
|
oldest_frame_item = _frameBuffersTSOrder.Next(oldest_frame_item);
|
||||||
}
|
}
|
||||||
if (oldestFrame == NULL) {
|
|
||||||
// No complete frame no point to continue
|
if (oldest_frame == NULL) {
|
||||||
|
// No complete frame no point to continue.
|
||||||
|
return NULL;
|
||||||
|
} else if (_waitingForKeyFrame &&
|
||||||
|
oldest_frame->FrameType() != kVideoFrameKey) {
|
||||||
|
// We are waiting for a key frame.
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a complete frame.
|
// We have a complete continuous frame.
|
||||||
// Check if it's continuous, otherwise we are missing a full frame.
|
return oldest_frame_item;
|
||||||
|
|
||||||
// Use pictureId if available. Otherwise use seqNum and not timestamps, as
|
|
||||||
// a complete frame might be lost.
|
|
||||||
// First determine if we are waiting for a key frame.
|
|
||||||
if (_waitingForKeyFrame && oldestFrame->FrameType() != kVideoFrameKey) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// We have a complete frame - establish continuity.
|
|
||||||
if (_lastDecodedState.init()) {
|
|
||||||
return oldestFrameItem;
|
|
||||||
} else if (!_lastDecodedState.ContinuousFrame(oldestFrame)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return oldestFrameItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call from inside the critical section _critSect
|
// Call from inside the critical section _critSect
|
||||||
@@ -1771,10 +1776,8 @@ void VCMJitterBuffer::VerifyAndSetPreviousFrameLost(VCMFrameBuffer& frame) {
|
|||||||
if (frame.FrameType() == kVideoFrameKey)
|
if (frame.FrameType() == kVideoFrameKey)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_lastDecodedState.init() ||
|
if (!_lastDecodedState.ContinuousFrame(&frame))
|
||||||
!_lastDecodedState.ContinuousFrame(&frame)) {
|
|
||||||
frame.SetPreviousFrameLoss();
|
frame.SetPreviousFrameLoss();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user