Revert 3892 "VCM/JB: Using last decoded state for waiting for key"

> VCM/JB: Using last decoded state for waiting for key
> 
> Review URL: https://webrtc-codereview.appspot.com/1323006

Although I have no idea why, it appears this might be causing failures in ViEStandardIntegrationTest.RunsFileTestWithoutErrors. I was unable to reproduce locally. This is a trial revert to verify. If the errors continue to happen, I will restore this change.

TBR=mikhal@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3896 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org
2013-04-24 02:13:18 +00:00
parent 2e65346e98
commit df9c0e5ec9
4 changed files with 40 additions and 22 deletions

View File

@ -149,11 +149,8 @@ bool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const {
// Return true when in initial state. // Return true when in initial state.
// Note that when a method is not applicable it will return false. // Note that when a method is not applicable it will return false.
assert(frame != NULL); assert(frame != NULL);
if (in_initial_state_) { if (in_initial_state_)
// Always start with a key frame. return true;
if (frame->FrameType() == kVideoFrameKey) return true;
return false;
}
if (!ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) { if (!ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) {
// Base layers are not continuous or temporal layers are inactive. // Base layers are not continuous or temporal layers are inactive.

View File

@ -30,9 +30,8 @@ TEST(TestDecodingState, Sanity) {
TEST(TestDecodingState, FrameContinuity) { TEST(TestDecodingState, FrameContinuity) {
VCMDecodingState dec_state; VCMDecodingState dec_state;
// Check that makes decision based on correct method. // Check that makes decision based on correct method.
VCMFrameBuffer frame, frame_key; VCMFrameBuffer frame;
frame.SetState(kStateEmpty); frame.SetState(kStateEmpty);
frame_key.SetState(kStateEmpty);
VCMPacket* packet = new VCMPacket(); VCMPacket* packet = new VCMPacket();
packet->isFirstPacket = 1; packet->isFirstPacket = 1;
packet->timestamp = 1; packet->timestamp = 1;
@ -41,15 +40,11 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codec = kRTPVideoVP8; packet->codecSpecificHeader.codec = kRTPVideoVP8;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x007F; packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x007F;
frame.InsertPacket(*packet, 0, false, 0); frame.InsertPacket(*packet, 0, false, 0);
// Always start with a key frame. // Should return true on init.
dec_state.Reset(); dec_state.Reset();
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
packet->frameType = kVideoFrameKey;
frame_key.InsertPacket(*packet, 0, false, 0);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key));
dec_state.SetState(&frame); dec_state.SetState(&frame);
frame.Reset(); frame.Reset();
packet->frameType = kVideoFrameDelta;
// Use pictureId // Use pictureId
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x0002; packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x0002;
frame.InsertPacket(*packet, 0, false, 0); frame.InsertPacket(*packet, 0, false, 0);
@ -463,4 +458,5 @@ TEST(TestDecodingState, OldInput) {
delete packet; delete packet;
} }
} // namespace webrtc } // namespace webrtc

View File

@ -105,6 +105,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
nack_seq_nums_(), nack_seq_nums_(),
max_nack_list_size_(0), max_nack_list_size_(0),
max_packet_age_to_nack_(0), max_packet_age_to_nack_(0),
waiting_for_key_frame_(false),
decode_with_errors_(false) { decode_with_errors_(false) {
memset(frame_buffers_, 0, sizeof(frame_buffers_)); memset(frame_buffers_, 0, sizeof(frame_buffers_));
memset(receive_statistics_, 0, sizeof(receive_statistics_)); memset(receive_statistics_, 0, sizeof(receive_statistics_));
@ -146,6 +147,7 @@ void VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs) {
inter_frame_delay_ = rhs.inter_frame_delay_; inter_frame_delay_ = rhs.inter_frame_delay_;
waiting_for_completion_ = rhs.waiting_for_completion_; waiting_for_completion_ = rhs.waiting_for_completion_;
rtt_ms_ = rhs.rtt_ms_; rtt_ms_ = rhs.rtt_ms_;
waiting_for_key_frame_ = rhs.waiting_for_key_frame_;
first_packet_ = rhs.first_packet_; first_packet_ = rhs.first_packet_;
last_decoded_state_ = rhs.last_decoded_state_; last_decoded_state_ = rhs.last_decoded_state_;
num_not_decodable_packets_ = rhs.num_not_decodable_packets_; num_not_decodable_packets_ = rhs.num_not_decodable_packets_;
@ -199,9 +201,9 @@ void VCMJitterBuffer::Start() {
waiting_for_completion_.timestamp = 0; waiting_for_completion_.timestamp = 0;
waiting_for_completion_.latest_packet_time = -1; waiting_for_completion_.latest_packet_time = -1;
first_packet_ = true; first_packet_ = true;
waiting_for_key_frame_ = false;
rtt_ms_ = kDefaultRtt; rtt_ms_ = kDefaultRtt;
num_not_decodable_packets_ = 0; num_not_decodable_packets_ = 0;
last_decoded_state_.Reset();
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
VCMId(vcm_id_, receiver_id_), "JB(0x%x): Jitter buffer: start", VCMId(vcm_id_, receiver_id_), "JB(0x%x): Jitter buffer: start",
@ -439,6 +441,10 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
CleanUpOldOrEmptyFrames(); CleanUpOldOrEmptyFrames();
if (last_decoded_state_.in_initial_state()) {
waiting_for_key_frame_ = true;
}
FrameList::iterator it = FindOldestCompleteContinuousFrame(); FrameList::iterator it = FindOldestCompleteContinuousFrame();
if (it == frame_list_.end()) { if (it == frame_list_.end()) {
const int64_t end_wait_time_ms = clock_->TimeInMilliseconds() + const int64_t end_wait_time_ms = clock_->TimeInMilliseconds() +
@ -489,6 +495,12 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
VCMFrameBuffer* oldest_frame = *it; VCMFrameBuffer* oldest_frame = *it;
// Are we waiting for a key frame?
if (waiting_for_key_frame_ && oldest_frame->FrameType() != kVideoFrameKey) {
crit_sect_->Leave();
return NULL;
}
it = frame_list_.erase(it); it = frame_list_.erase(it);
if (frame_list_.empty()) { if (frame_list_.empty()) {
TRACE_EVENT_INSTANT1("webrtc", "JB::FrameListEmptied", TRACE_EVENT_INSTANT1("webrtc", "JB::FrameListEmptied",
@ -506,6 +518,10 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
oldest_frame->SetState(kStateDecoding); oldest_frame->SetState(kStateDecoding);
if (oldest_frame->FrameType() == kVideoFrameKey) {
waiting_for_key_frame_ = false;
}
// We have a frame - update decoded state with frame info. // We have a frame - update decoded state with frame info.
last_decoded_state_.SetState(oldest_frame); last_decoded_state_.SetState(oldest_frame);
DropPacketsFromNackList(last_decoded_state_.sequence_num()); DropPacketsFromNackList(last_decoded_state_.sequence_num());
@ -537,12 +553,6 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecoding() {
return NULL; return NULL;
} }
// Always start with a key frame.
if (last_decoded_state_.in_initial_state() &&
oldest_frame->FrameType() != kVideoFrameKey) {
return NULL;
}
// Incomplete frame pulled out from jitter buffer, // Incomplete frame pulled out from jitter buffer,
// update the jitter estimate with what we currently know. // update the jitter estimate with what we currently know.
// This frame shouldn't have been retransmitted, but if we recently // This frame shouldn't have been retransmitted, but if we recently
@ -577,6 +587,10 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecoding() {
// Set as decoding. Propagates the missing_frame bit. // Set as decoding. Propagates the missing_frame bit.
oldest_frame->SetState(kStateDecoding); oldest_frame->SetState(kStateDecoding);
if (oldest_frame->FrameType() == kVideoFrameKey) {
waiting_for_key_frame_ = false;
}
num_not_decodable_packets_ += oldest_frame->NotDecodablePackets(); num_not_decodable_packets_ += oldest_frame->NotDecodablePackets();
// We have a frame - update decoded state with frame info. // We have a frame - update decoded state with frame info.
@ -990,6 +1004,9 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecodingNACK() {
// First look for a complete continuous frame. // First look for a complete continuous frame.
// When waiting for nack, wait for a key frame, if a continuous frame cannot // When waiting for nack, wait for a key frame, if a continuous frame cannot
// be determined (i.e. initial decoding state). // be determined (i.e. initial decoding state).
if (last_decoded_state_.in_initial_state()) {
waiting_for_key_frame_ = true;
}
FrameList::iterator it = FindOldestCompleteContinuousFrame(); FrameList::iterator it = FindOldestCompleteContinuousFrame();
if (it == frame_list_.end()) { if (it == frame_list_.end()) {
// If we didn't find one we're good with a complete key frame. // If we didn't find one we're good with a complete key frame.
@ -1000,7 +1017,6 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecodingNACK() {
} }
} }
VCMFrameBuffer* oldest_frame = *it; VCMFrameBuffer* oldest_frame = *it;
// Update jitter estimate // Update jitter estimate
const bool retransmitted = (oldest_frame->GetNackCount() > 0); const bool retransmitted = (oldest_frame->GetNackCount() > 0);
if (retransmitted) { if (retransmitted) {
@ -1023,6 +1039,10 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecodingNACK() {
// decoder. // decoder.
oldest_frame->SetState(kStateDecoding); oldest_frame->SetState(kStateDecoding);
if (oldest_frame->FrameType() == kVideoFrameKey) {
waiting_for_key_frame_ = false;
}
// We have a frame - update decoded state with frame info. // We have a frame - update decoded state with frame info.
last_decoded_state_.SetState(oldest_frame); last_decoded_state_.SetState(oldest_frame);
DropPacketsFromNackList(last_decoded_state_.sequence_num()); DropPacketsFromNackList(last_decoded_state_.sequence_num());
@ -1100,6 +1120,7 @@ bool VCMJitterBuffer::RecycleFramesUntilKeyFrame() {
TRACE_EVENT_INSTANT1("webrtc", "JB::FrameListEmptied", TRACE_EVENT_INSTANT1("webrtc", "JB::FrameListEmptied",
"type", "RecycleFramesUntilKeyFrame"); "type", "RecycleFramesUntilKeyFrame");
} }
waiting_for_key_frame_ = true;
last_decoded_state_.Reset(); // TODO(mikhal): No sync. last_decoded_state_.Reset(); // TODO(mikhal): No sync.
missing_sequence_numbers_.clear(); missing_sequence_numbers_.clear();
return false; return false;
@ -1241,8 +1262,11 @@ FrameList::iterator VCMJitterBuffer::FindOldestCompleteContinuousFrame() {
if (oldest_frame == NULL) { if (oldest_frame == NULL) {
// No complete frame no point to continue. // No complete frame no point to continue.
return frame_list_.end(); return frame_list_.end();
} else if (waiting_for_key_frame_ &&
oldest_frame->FrameType() != kVideoFrameKey) {
// We are waiting for a key frame.
return frame_list_.end();
} }
// We have a complete continuous frame. // We have a complete continuous frame.
return it; return it;
} }

View File

@ -294,6 +294,7 @@ class VCMJitterBuffer {
std::vector<uint16_t> nack_seq_nums_; std::vector<uint16_t> nack_seq_nums_;
size_t max_nack_list_size_; size_t max_nack_list_size_;
int max_packet_age_to_nack_; // Measured in sequence numbers. int max_packet_age_to_nack_; // Measured in sequence numbers.
bool waiting_for_key_frame_;
bool decode_with_errors_; bool decode_with_errors_;
DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer); DISALLOW_COPY_AND_ASSIGN(VCMJitterBuffer);