Follow-up changes to kSelectiveErrors
Committing cl for agalusza (cl 1992004) TEST = trybots R=marpan@google.com Review URL: https://webrtc-codereview.appspot.com/2085004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4587 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
60bdb07a16
commit
dbf6a81cb5
@ -208,10 +208,10 @@ VCMFrameBuffer::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VCMFrameBuffer::ClearStateIfIncomplete() {
|
VCMFrameBuffer::SetNotDecodableIfIncomplete() {
|
||||||
if (_state == kStateDecodable) {
|
if (_state == kStateDecodable) {
|
||||||
_state = kStateIncomplete;
|
_state = kStateIncomplete;
|
||||||
_sessionInfo.ClearStateIfIncomplete();
|
_sessionInfo.SetNotDecodableIfIncomplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class VCMFrameBuffer : public VCMEncodedFrame {
|
|||||||
// Used by the dual decoder. After the mode is changed to kNoErrors from
|
// Used by the dual decoder. After the mode is changed to kNoErrors from
|
||||||
// kWithErrors or kSelective errors, any states that have been marked
|
// kWithErrors or kSelective errors, any states that have been marked
|
||||||
// decodable and are not complete are marked as non-decodable.
|
// decodable and are not complete are marked as non-decodable.
|
||||||
void ClearStateIfIncomplete();
|
void SetNotDecodableIfIncomplete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetState(VCMFrameBufferStateEnum state); // Set state of frame
|
void SetState(VCMFrameBufferStateEnum state); // Set state of frame
|
||||||
|
@ -756,45 +756,35 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
|
|||||||
" size:%d type %d",
|
" size:%d type %d",
|
||||||
this, frame, frame->Length(), frame->FrameType());
|
this, frame, frame->Length(), frame->FrameType());
|
||||||
}
|
}
|
||||||
*retransmitted = (frame->GetNackCount() > 0);
|
|
||||||
CountFrame(*frame);
|
CountFrame(*frame);
|
||||||
frame->SetCountedFrame(true);
|
frame->SetCountedFrame(true);
|
||||||
|
if (previous_state == kStateComplete) {
|
||||||
|
*retransmitted = (frame->GetNackCount() > 0);
|
||||||
|
packet_event_->Set();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case kDecodableSession: {
|
||||||
*retransmitted = (frame->GetNackCount() > 0);
|
*retransmitted = (frame->GetNackCount() > 0);
|
||||||
if (IsContinuous(*frame) && previous_state != kStateComplete) {
|
if (previous_state != kStateDecodable) {
|
||||||
if (previous_state != kStateDecodable) {
|
if (IsContinuous(*frame) || decode_error_mode_ == kWithErrors) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
incomplete_frames_.PopFrame(packet.timestamp);
|
incomplete_frames_.PopFrame(packet.timestamp);
|
||||||
}
|
}
|
||||||
decodable_frames_.InsertFrame(frame);
|
decodable_frames_.InsertFrame(frame);
|
||||||
FindAndInsertContinuousFrames(*frame);
|
FindAndInsertContinuousFrames(*frame);
|
||||||
|
if (buffer_return == kCompleteSession) {
|
||||||
|
// Signal that we have a complete session
|
||||||
|
frame_event_->Set();
|
||||||
|
}
|
||||||
|
} else if (first) {
|
||||||
|
incomplete_frames_.InsertFrame(frame);
|
||||||
}
|
}
|
||||||
// Signal that we have a decodable frame.
|
|
||||||
frame_event_->Set();
|
|
||||||
} else if (first) {
|
|
||||||
incomplete_frames_.InsertFrame(frame);
|
|
||||||
}
|
}
|
||||||
// Signal that we have a received packet.
|
// Signal that we have a received packet.
|
||||||
packet_event_->Set();
|
packet_event_->Set();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kDecodableSession:
|
|
||||||
assert(previous_state != kStateComplete);
|
|
||||||
*retransmitted = (frame->GetNackCount() > 0);
|
|
||||||
frame->SetCountedFrame(true);
|
|
||||||
if ((IsContinuous(*frame) || decode_error_mode_ == kWithErrors)
|
|
||||||
&& previous_state != kStateDecodable) {
|
|
||||||
incomplete_frames_.PopFrame(packet.timestamp);
|
|
||||||
decodable_frames_.InsertFrame(frame);
|
|
||||||
FindAndInsertContinuousFrames(*frame);
|
|
||||||
// Signal that we have a decodable frame.
|
|
||||||
frame_event_->Set();
|
|
||||||
} else if (first) {
|
|
||||||
ret = kFirstPacket;
|
|
||||||
incomplete_frames_.InsertFrame(frame);
|
|
||||||
}
|
|
||||||
// Signal that we have a received packet.
|
|
||||||
packet_event_->Set();
|
|
||||||
break;
|
|
||||||
case kIncomplete: {
|
case kIncomplete: {
|
||||||
// No point in storing empty continuous frames.
|
// No point in storing empty continuous frames.
|
||||||
if (frame->GetState() == kStateEmpty &&
|
if (frame->GetState() == kStateEmpty &&
|
||||||
@ -807,7 +797,6 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
|
|||||||
decodable_frames_.PopFrame(packet.timestamp);
|
decodable_frames_.PopFrame(packet.timestamp);
|
||||||
incomplete_frames_.InsertFrame(frame);
|
incomplete_frames_.InsertFrame(frame);
|
||||||
} else if (first) {
|
} else if (first) {
|
||||||
ret = kFirstPacket;
|
|
||||||
incomplete_frames_.InsertFrame(frame);
|
incomplete_frames_.InsertFrame(frame);
|
||||||
}
|
}
|
||||||
// Signal that we have received a packet.
|
// Signal that we have received a packet.
|
||||||
@ -1042,7 +1031,8 @@ uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
|||||||
return &nack_seq_nums_[0];
|
return &nack_seq_nums_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCMJitterBuffer::DecodeErrorMode(VCMDecodeErrorMode error_mode) {
|
void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) {
|
||||||
|
CriticalSectionScoped cs(crit_sect_);
|
||||||
// If we are not moving from kWithErrors or KSelectiveErrors to kNoErrors,
|
// If we are not moving from kWithErrors or KSelectiveErrors to kNoErrors,
|
||||||
// set decode_error_mode_ and apply new error mode only to new packets.
|
// set decode_error_mode_ and apply new error mode only to new packets.
|
||||||
// Also no need for further processing if we have no old, previously
|
// Also no need for further processing if we have no old, previously
|
||||||
@ -1068,7 +1058,7 @@ void VCMJitterBuffer::DecodeErrorMode(VCMDecodeErrorMode error_mode) {
|
|||||||
frame = it->second;
|
frame = it->second;
|
||||||
++it;
|
++it;
|
||||||
frame = decodable_frames_.PopFrame(frame->TimeStamp());
|
frame = decodable_frames_.PopFrame(frame->TimeStamp());
|
||||||
frame->ClearStateIfIncomplete();
|
frame->SetNotDecodableIfIncomplete();
|
||||||
incomplete_frames_.InsertFrame(frame);
|
incomplete_frames_.InsertFrame(frame);
|
||||||
}
|
}
|
||||||
decode_error_mode_ = error_mode;
|
decode_error_mode_ = error_mode;
|
||||||
|
@ -179,7 +179,7 @@ class VCMJitterBuffer {
|
|||||||
// Setting kWithErrors and kSelectiveErrors will take full effect once the
|
// Setting kWithErrors and kSelectiveErrors will take full effect once the
|
||||||
// existing incomplete frames leave the JB or have a packet added (as that
|
// existing incomplete frames leave the JB or have a packet added (as that
|
||||||
// would cause their state to be reevlauated).
|
// would cause their state to be reevlauated).
|
||||||
void DecodeErrorMode(VCMDecodeErrorMode error_mode);
|
void SetDecodeErrorMode(VCMDecodeErrorMode error_mode);
|
||||||
int64_t LastDecodedTimestamp() const;
|
int64_t LastDecodedTimestamp() const;
|
||||||
VCMDecodeErrorMode decode_error_mode() const {return decode_error_mode_;}
|
VCMDecodeErrorMode decode_error_mode() const {return decode_error_mode_;}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ enum VCMFrameBufferEnum {
|
|||||||
kSizeError = -1,
|
kSizeError = -1,
|
||||||
kNoError = 0,
|
kNoError = 0,
|
||||||
kIncomplete = 1, // Frame incomplete.
|
kIncomplete = 1, // Frame incomplete.
|
||||||
kFirstPacket = 2,
|
|
||||||
kCompleteSession = 3, // at least one layer in the frame complete.
|
kCompleteSession = 3, // at least one layer in the frame complete.
|
||||||
kDecodableSession = 4, // Frame incomplete, but ready to be decoded
|
kDecodableSession = 4, // Frame incomplete, but ready to be decoded
|
||||||
kDuplicatePacket = 5 // We're receiving a duplicate packet.
|
kDuplicatePacket = 5 // We're receiving a duplicate packet.
|
||||||
|
@ -244,14 +244,14 @@ TEST_F(TestBasicJitterBuffer, StopRunning) {
|
|||||||
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
|
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
|
||||||
jitter_buffer_->Start();
|
jitter_buffer_->Start();
|
||||||
// Allow selective errors.
|
// Allow selective errors.
|
||||||
jitter_buffer_->DecodeErrorMode(kSelectiveErrors);
|
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
|
||||||
|
|
||||||
// No packets inserted.
|
// No packets inserted.
|
||||||
EXPECT_TRUE(NULL == DecodeCompleteFrame());
|
EXPECT_TRUE(NULL == DecodeCompleteFrame());
|
||||||
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
|
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
|
||||||
|
|
||||||
// Allow decoding with errors.
|
// Allow decoding with errors.
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
|
|
||||||
// No packets inserted.
|
// No packets inserted.
|
||||||
EXPECT_TRUE(NULL == DecodeCompleteFrame());
|
EXPECT_TRUE(NULL == DecodeCompleteFrame());
|
||||||
@ -280,7 +280,7 @@ TEST_F(TestBasicJitterBuffer, DualPacketFrame) {
|
|||||||
packet_->markerBit = false;
|
packet_->markerBit = false;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
// Should not be complete.
|
// Should not be complete.
|
||||||
@ -306,7 +306,7 @@ TEST_F(TestBasicJitterBuffer, 100PacketKeyFrame) {
|
|||||||
packet_->markerBit = false;
|
packet_->markerBit = false;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -360,7 +360,7 @@ TEST_F(TestBasicJitterBuffer, 100PacketDeltaFrame) {
|
|||||||
packet_->frameType = kVideoFrameDelta;
|
packet_->frameType = kVideoFrameDelta;
|
||||||
packet_->timestamp += 33 * 90;
|
packet_->timestamp += 33 * 90;
|
||||||
|
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
frame_out = DecodeCompleteFrame();
|
frame_out = DecodeCompleteFrame();
|
||||||
@ -406,7 +406,7 @@ TEST_F(TestBasicJitterBuffer, PacketReorderingReverseOrder) {
|
|||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -448,7 +448,7 @@ TEST_F(TestBasicJitterBuffer, FrameReordering2Frames2PacketsEach) {
|
|||||||
packet_->markerBit = false;
|
packet_->markerBit = false;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -475,7 +475,7 @@ TEST_F(TestBasicJitterBuffer, FrameReordering2Frames2PacketsEach) {
|
|||||||
packet_->seqNum = seq_num_;
|
packet_->seqNum = seq_num_;
|
||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
frame_out = DecodeCompleteFrame();
|
frame_out = DecodeCompleteFrame();
|
||||||
@ -514,7 +514,7 @@ TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
|
|||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -550,7 +550,7 @@ TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
|
|||||||
packet_->insertStartCode = true;
|
packet_->insertStartCode = true;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -571,8 +571,9 @@ TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
|
|||||||
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
|
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorrs) {
|
// Test threshold conditions of decodable state.
|
||||||
jitter_buffer_->DecodeErrorMode(kSelectiveErrors);
|
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsThresholdCheck) {
|
||||||
|
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
|
||||||
// Always start with a key frame. Use 10 packets to test Decodable State
|
// Always start with a key frame. Use 10 packets to test Decodable State
|
||||||
// boundaries.
|
// boundaries.
|
||||||
packet_->frameType = kVideoFrameKey;
|
packet_->frameType = kVideoFrameKey;
|
||||||
@ -582,7 +583,7 @@ TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorrs) {
|
|||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
@ -614,7 +615,7 @@ TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorrs) {
|
|||||||
packet_->markerBit = false;
|
packet_->markerBit = false;
|
||||||
packet_->seqNum += 100;
|
packet_->seqNum += 100;
|
||||||
packet_->timestamp += 33*90*8;
|
packet_->timestamp += 33*90*8;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
@ -654,8 +655,136 @@ TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorrs) {
|
|||||||
&retransmitted));
|
&retransmitted));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure first packet is present before a frame can be decoded.
|
||||||
|
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsIncompleteKey) {
|
||||||
|
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
|
||||||
|
// Always start with a key frame.
|
||||||
|
packet_->frameType = kVideoFrameKey;
|
||||||
|
packet_->isFirstPacket = true;
|
||||||
|
packet_->markerBit = true;
|
||||||
|
packet_->seqNum = seq_num_;
|
||||||
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
|
bool retransmitted = false;
|
||||||
|
EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
|
CheckOutFrame(frame_out, size_, false);
|
||||||
|
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
|
||||||
|
|
||||||
|
// An incomplete frame can only be decoded once a subsequent frame has begun
|
||||||
|
// to arrive. Insert packet in distant frame for this purpose.
|
||||||
|
packet_->frameType = kVideoFrameDelta;
|
||||||
|
packet_->isFirstPacket = false;
|
||||||
|
packet_->markerBit = false;
|
||||||
|
packet_->seqNum += 100;
|
||||||
|
packet_->timestamp += 33*90*8;
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
uint32_t timestamp;
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
|
// Insert second frame - an incomplete key frame.
|
||||||
|
packet_->frameType = kVideoFrameKey;
|
||||||
|
packet_->isFirstPacket = true;
|
||||||
|
packet_->seqNum -= 99;
|
||||||
|
packet_->timestamp -= 33*90*7;
|
||||||
|
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
|
// Insert a few more packets. Make sure we're waiting for the key frame to be
|
||||||
|
// complete.
|
||||||
|
packet_->isFirstPacket = false;
|
||||||
|
for (int i = 1; i < 5; ++i) {
|
||||||
|
packet_->seqNum++;
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete key frame.
|
||||||
|
packet_->markerBit = true;
|
||||||
|
packet_->seqNum++;
|
||||||
|
EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
frame_out = DecodeCompleteFrame();
|
||||||
|
CheckOutFrame(frame_out, 6 * size_, false);
|
||||||
|
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure first packet is present before a frame can be decoded.
|
||||||
|
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsMissingFirstPacket) {
|
||||||
|
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
|
||||||
|
// Always start with a key frame.
|
||||||
|
packet_->frameType = kVideoFrameKey;
|
||||||
|
packet_->isFirstPacket = true;
|
||||||
|
packet_->markerBit = true;
|
||||||
|
packet_->seqNum = seq_num_;
|
||||||
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
|
bool retransmitted = false;
|
||||||
|
EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
|
CheckOutFrame(frame_out, size_, false);
|
||||||
|
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
|
||||||
|
|
||||||
|
// An incomplete frame can only be decoded once a subsequent frame has begun
|
||||||
|
// to arrive. Insert packet in distant frame for this purpose.
|
||||||
|
packet_->frameType = kVideoFrameDelta;
|
||||||
|
packet_->isFirstPacket = false;
|
||||||
|
packet_->markerBit = false;
|
||||||
|
packet_->seqNum += 100;
|
||||||
|
packet_->timestamp += 33*90*8;
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
uint32_t timestamp;
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
|
// Insert second frame with the first packet missing. Make sure we're waiting
|
||||||
|
// for the key frame to be complete.
|
||||||
|
packet_->seqNum -= 98;
|
||||||
|
packet_->timestamp -= 33*90*7;
|
||||||
|
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
packet_->seqNum++;
|
||||||
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add first packet. Frame should now be decodable, but incomplete.
|
||||||
|
packet_->isFirstPacket = true;
|
||||||
|
packet_->seqNum -= 6;
|
||||||
|
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
|
||||||
|
&retransmitted));
|
||||||
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
|
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
|
frame_out = DecodeIncompleteFrame();
|
||||||
|
CheckOutFrame(frame_out, 7 * size_, false);
|
||||||
|
EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure incoplete decodable packets are removed from decodable frames
|
||||||
|
// and marked incomplete if the decode error mode is changed from kWithErrors
|
||||||
|
// or kSelectiveErrors to kNoErrors.
|
||||||
|
// Also make sure these frames are marked complete once all the packets are
|
||||||
|
// present (ie they are not dropped).
|
||||||
TEST_F(TestBasicJitterBuffer, PacketLossStateChangedFromErrorsToNone) {
|
TEST_F(TestBasicJitterBuffer, PacketLossStateChangedFromErrorsToNone) {
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
|
|
||||||
// First frame is always a key frame.
|
// First frame is always a key frame.
|
||||||
packet_->frameType = kVideoFrameKey;
|
packet_->frameType = kVideoFrameKey;
|
||||||
@ -696,7 +825,7 @@ TEST_F(TestBasicJitterBuffer, PacketLossStateChangedFromErrorsToNone) {
|
|||||||
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
|
|
||||||
jitter_buffer_->DecodeErrorMode(kNoErrors);
|
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
|
||||||
|
|
||||||
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextCompleteTimestamp(0, ×tamp));
|
||||||
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp));
|
||||||
@ -737,7 +866,7 @@ TEST_F(TestBasicJitterBuffer, PacketLoss) {
|
|||||||
// Select a start seqNum which triggers a difficult wrap situation
|
// Select a start seqNum which triggers a difficult wrap situation
|
||||||
// The JB will only output (incomplete)frames if the next one has started
|
// The JB will only output (incomplete)frames if the next one has started
|
||||||
// to arrive. Start by inserting one frame (key).
|
// to arrive. Start by inserting one frame (key).
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
seq_num_ = 0xffff - 4;
|
seq_num_ = 0xffff - 4;
|
||||||
seq_num_++;
|
seq_num_++;
|
||||||
packet_->frameType = kVideoFrameKey;
|
packet_->frameType = kVideoFrameKey;
|
||||||
@ -845,7 +974,7 @@ TEST_F(TestBasicJitterBuffer, DeltaFrame100PacketsWithSeqNumWrap) {
|
|||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -893,7 +1022,7 @@ TEST_F(TestBasicJitterBuffer, PacketReorderingReverseWithNegSeqNumWrap) {
|
|||||||
packet_->seqNum = seq_num_;
|
packet_->seqNum = seq_num_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
|
|
||||||
@ -1025,7 +1154,7 @@ TEST_F(TestBasicJitterBuffer, TimestampWrap) {
|
|||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
|
||||||
@ -1054,7 +1183,7 @@ TEST_F(TestBasicJitterBuffer, TimestampWrap) {
|
|||||||
packet_->seqNum = seq_num_;
|
packet_->seqNum = seq_num_;
|
||||||
packet_->timestamp = timestamp_;
|
packet_->timestamp = timestamp_;
|
||||||
|
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
|
|
||||||
frame_out = DecodeCompleteFrame();
|
frame_out = DecodeCompleteFrame();
|
||||||
@ -1177,7 +1306,7 @@ TEST_F(TestBasicJitterBuffer, DeltaFrameWithMoreThanMaxNumberOfPackets) {
|
|||||||
packet_->seqNum = seq_num_;
|
packet_->seqNum = seq_num_;
|
||||||
|
|
||||||
if (firstPacket) {
|
if (firstPacket) {
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
|
||||||
&retransmitted));
|
&retransmitted));
|
||||||
firstPacket = false;
|
firstPacket = false;
|
||||||
} else {
|
} else {
|
||||||
@ -1259,7 +1388,7 @@ TEST_F(TestBasicJitterBuffer, ExceedNumOfFrameWithSeqNumWrap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
|
TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
seq_num_ = 3;
|
seq_num_ = 3;
|
||||||
// Insert one empty packet per frame, should never return the last timestamp
|
// Insert one empty packet per frame, should never return the last timestamp
|
||||||
// inserted. Only return empty frames in the presence of subsequent frames.
|
// inserted. Only return empty frames in the presence of subsequent frames.
|
||||||
@ -1286,7 +1415,7 @@ TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
|
|||||||
|
|
||||||
TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
|
TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
|
||||||
jitter_buffer_->SetNackMode(kNoNack, -1, -1);
|
jitter_buffer_->SetNackMode(kNoNack, -1, -1);
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
seq_num_ ++;
|
seq_num_ ++;
|
||||||
timestamp_ += 33 * 90;
|
timestamp_ += 33 * 90;
|
||||||
int insertedLength = 0;
|
int insertedLength = 0;
|
||||||
@ -1472,7 +1601,7 @@ TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
|
|||||||
// Test that a we cannot get incomplete frames from the JB if we haven't
|
// Test that a we cannot get incomplete frames from the JB if we haven't
|
||||||
// received the marker bit, unless we have received a packet from a later
|
// received the marker bit, unless we have received a packet from a later
|
||||||
// timestamp.
|
// timestamp.
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
// Start with a complete key frame - insert and decode.
|
// Start with a complete key frame - insert and decode.
|
||||||
packet_->frameType = kVideoFrameKey;
|
packet_->frameType = kVideoFrameKey;
|
||||||
packet_->isFirstPacket = true;
|
packet_->isFirstPacket = true;
|
||||||
@ -1535,7 +1664,7 @@ TEST_F(TestRunningJitterBuffer, EmptyPackets) {
|
|||||||
EXPECT_EQ(kNoError, InsertPacketAndPop(4));
|
EXPECT_EQ(kNoError, InsertPacketAndPop(4));
|
||||||
EXPECT_FALSE(request_key_frame);
|
EXPECT_FALSE(request_key_frame);
|
||||||
// Insert 3 media packets.
|
// Insert 3 media packets.
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
EXPECT_FALSE(request_key_frame);
|
EXPECT_FALSE(request_key_frame);
|
||||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
EXPECT_FALSE(request_key_frame);
|
EXPECT_FALSE(request_key_frame);
|
||||||
@ -1636,7 +1765,7 @@ TEST_F(TestRunningJitterBuffer, TwoPacketsNonContinuous) {
|
|||||||
clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
|
clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
|
||||||
stream_generator_->GenerateFrame(kVideoFrameDelta, 2, 0,
|
stream_generator_->GenerateFrame(kVideoFrameDelta, 2, 0,
|
||||||
clock_->TimeInMilliseconds());
|
clock_->TimeInMilliseconds());
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(1));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
||||||
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(1));
|
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(1));
|
||||||
EXPECT_FALSE(DecodeCompleteFrame());
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(0));
|
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(0));
|
||||||
@ -1765,7 +1894,7 @@ TEST_F(TestJitterBufferNack, NackListBuiltBeforeFirstDecode) {
|
|||||||
stream_generator_->GenerateFrame(kVideoFrameDelta, 2, 0,
|
stream_generator_->GenerateFrame(kVideoFrameDelta, 2, 0,
|
||||||
clock_->TimeInMilliseconds());
|
clock_->TimeInMilliseconds());
|
||||||
stream_generator_->NextPacket(NULL); // Drop packet.
|
stream_generator_->NextPacket(NULL); // Drop packet.
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
EXPECT_TRUE(DecodeCompleteFrame());
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
uint16_t nack_list_size = 0;
|
uint16_t nack_list_size = 0;
|
||||||
bool extended = false;
|
bool extended = false;
|
||||||
@ -1781,7 +1910,7 @@ TEST_F(TestJitterBufferNack, VerifyRetransmittedFlag) {
|
|||||||
VCMPacket packet;
|
VCMPacket packet;
|
||||||
stream_generator_->PopPacket(&packet, 0);
|
stream_generator_->PopPacket(&packet, 0);
|
||||||
bool retransmitted = false;
|
bool retransmitted = false;
|
||||||
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(packet, &retransmitted));
|
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(packet, &retransmitted));
|
||||||
EXPECT_FALSE(retransmitted);
|
EXPECT_FALSE(retransmitted);
|
||||||
// Drop second packet.
|
// Drop second packet.
|
||||||
stream_generator_->PopPacket(&packet, 1);
|
stream_generator_->PopPacket(&packet, 1);
|
||||||
@ -1805,7 +1934,7 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrame) {
|
|||||||
stream_generator_->Init(0, 0, clock_->TimeInMilliseconds());
|
stream_generator_->Init(0, 0, clock_->TimeInMilliseconds());
|
||||||
stream_generator_->GenerateFrame(kVideoFrameKey, 3, 0,
|
stream_generator_->GenerateFrame(kVideoFrameKey, 3, 0,
|
||||||
clock_->TimeInMilliseconds());
|
clock_->TimeInMilliseconds());
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
// Drop second packet.
|
// Drop second packet.
|
||||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
||||||
EXPECT_FALSE(DecodeCompleteFrame());
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
@ -1825,14 +1954,14 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
|
|||||||
// First frame is delta.
|
// First frame is delta.
|
||||||
stream_generator_->GenerateFrame(kVideoFrameDelta, 3, 0,
|
stream_generator_->GenerateFrame(kVideoFrameDelta, 3, 0,
|
||||||
clock_->TimeInMilliseconds());
|
clock_->TimeInMilliseconds());
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
// Drop second packet in frame.
|
// Drop second packet in frame.
|
||||||
ASSERT_TRUE(stream_generator_->PopPacket(&packet, 0));
|
ASSERT_TRUE(stream_generator_->PopPacket(&packet, 0));
|
||||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
// Second frame is key.
|
// Second frame is key.
|
||||||
stream_generator_->GenerateFrame(kVideoFrameKey, 3, 0,
|
stream_generator_->GenerateFrame(kVideoFrameKey, 3, 0,
|
||||||
clock_->TimeInMilliseconds() + 10);
|
clock_->TimeInMilliseconds() + 10);
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
// Drop second packet in frame.
|
// Drop second packet in frame.
|
||||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
||||||
EXPECT_FALSE(DecodeCompleteFrame());
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
@ -1847,7 +1976,7 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
|
|||||||
|
|
||||||
TEST_F(TestJitterBufferNack, NormalOperation) {
|
TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||||
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
|
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
|
||||||
jitter_buffer_->DecodeErrorMode(kWithErrors);
|
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
|
||||||
|
|
||||||
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
|
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
|
||||||
EXPECT_TRUE(DecodeIncompleteFrame());
|
EXPECT_TRUE(DecodeIncompleteFrame());
|
||||||
@ -1894,7 +2023,7 @@ TEST_F(TestJitterBufferNack, NormalOperationWrap) {
|
|||||||
EXPECT_TRUE(DecodeCompleteFrame());
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
stream_generator_->GenerateFrame(kVideoFrameDelta, 100, 0,
|
stream_generator_->GenerateFrame(kVideoFrameDelta, 100, 0,
|
||||||
clock_->TimeInMilliseconds());
|
clock_->TimeInMilliseconds());
|
||||||
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
while (stream_generator_->PacketsRemaining() > 1) {
|
while (stream_generator_->PacketsRemaining() > 1) {
|
||||||
if (stream_generator_->NextSequenceNumber() % 10 != 0) {
|
if (stream_generator_->NextSequenceNumber() % 10 != 0) {
|
||||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
|
@ -313,14 +313,11 @@ VCMReceiverState VCMReceiver::State() const {
|
|||||||
return state_;
|
return state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCMReceiver::SetDecodeErrorMode(
|
void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
|
||||||
VCMDecodeErrorMode decode_error_mode) {
|
jitter_buffer_.SetDecodeErrorMode(decode_error_mode);
|
||||||
CriticalSectionScoped cs(crit_sect_);
|
|
||||||
jitter_buffer_.DecodeErrorMode(decode_error_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
|
VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
|
||||||
CriticalSectionScoped cs(crit_sect_);
|
|
||||||
return jitter_buffer_.decode_error_mode();
|
return jitter_buffer_.decode_error_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ int VCMSessionInfo::MakeDecodable() {
|
|||||||
return return_length;
|
return return_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCMSessionInfo::ClearStateIfIncomplete() {
|
void VCMSessionInfo::SetNotDecodableIfIncomplete() {
|
||||||
// We don't need to check for completeness first because the two are
|
// We don't need to check for completeness first because the two are
|
||||||
// orthogonal. If complete_ is true, decodable_ is irrelevant.
|
// orthogonal. If complete_ is true, decodable_ is irrelevant.
|
||||||
decodable_ = false;
|
decodable_ = false;
|
||||||
|
@ -70,7 +70,7 @@ class VCMSessionInfo {
|
|||||||
// Used by the dual decoder. After the mode is changed to kNoErrors from
|
// Used by the dual decoder. After the mode is changed to kNoErrors from
|
||||||
// kWithErrors or kSelective errors, any states that have been marked
|
// kWithErrors or kSelective errors, any states that have been marked
|
||||||
// decodable and are not complete are marked as non-decodable.
|
// decodable and are not complete are marked as non-decodable.
|
||||||
void ClearStateIfIncomplete();
|
void SetNotDecodableIfIncomplete();
|
||||||
|
|
||||||
int SessionLength() const;
|
int SessionLength() const;
|
||||||
int NumPackets() const;
|
int NumPackets() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user