Start NACKing as soon as we have the first packet of a key frame.
BUG=1605 Review URL: https://webrtc-codereview.appspot.com/1307007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3855 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
bdb9b971be
commit
885cd13356
@ -216,6 +216,12 @@ VCMFrameBuffer::GetNackCount() const
|
|||||||
return _nackCount;
|
return _nackCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VCMFrameBuffer::HaveFirstPacket() const
|
||||||
|
{
|
||||||
|
return _sessionInfo.HaveFirstPacket();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VCMFrameBuffer::HaveLastPacket() const
|
VCMFrameBuffer::HaveLastPacket() const
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ public:
|
|||||||
|
|
||||||
bool IsRetransmitted() const;
|
bool IsRetransmitted() const;
|
||||||
bool IsSessionComplete() const;
|
bool IsSessionComplete() const;
|
||||||
|
bool HaveFirstPacket() const;
|
||||||
bool HaveLastPacket() const;
|
bool HaveLastPacket() const;
|
||||||
// Makes sure the session contain a decodable stream.
|
// Makes sure the session contain a decodable stream.
|
||||||
void MakeSessionDecodable();
|
void MakeSessionDecodable();
|
||||||
|
@ -878,11 +878,19 @@ uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (last_decoded_state_.in_initial_state()) {
|
if (last_decoded_state_.in_initial_state()) {
|
||||||
const bool have_non_empty_frame = frame_list_.end() != find_if(
|
bool first_frame_is_key = !frame_list_.empty() &&
|
||||||
frame_list_.begin(), frame_list_.end(), HasNonEmptyState);
|
frame_list_.front()->FrameType() == kVideoFrameKey &&
|
||||||
*request_key_frame = have_non_empty_frame;
|
frame_list_.front()->HaveFirstPacket();
|
||||||
*nack_list_size = 0;
|
if (!first_frame_is_key) {
|
||||||
return NULL;
|
const bool have_non_empty_frame = frame_list_.end() != find_if(
|
||||||
|
frame_list_.begin(), frame_list_.end(), HasNonEmptyState);
|
||||||
|
bool found_key_frame = RecycleFramesUntilKeyFrame();
|
||||||
|
if (!found_key_frame) {
|
||||||
|
*request_key_frame = have_non_empty_frame;
|
||||||
|
*nack_list_size = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (TooLargeNackList()) {
|
if (TooLargeNackList()) {
|
||||||
TRACE_EVENT_INSTANT1("webrtc", "JB::NackListTooLarge",
|
TRACE_EVENT_INSTANT1("webrtc", "JB::NackListTooLarge",
|
||||||
|
@ -494,6 +494,24 @@ TEST_F(TestJitterBufferNack, NackListBuiltBeforeFirstDecode) {
|
|||||||
EXPECT_TRUE(list != NULL);
|
EXPECT_TRUE(list != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrame) {
|
||||||
|
stream_generator->Init(0, 0, clock_->TimeInMilliseconds());
|
||||||
|
stream_generator->GenerateFrame(kVideoFrameKey, 3, 0,
|
||||||
|
clock_->TimeInMilliseconds());
|
||||||
|
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
||||||
|
// Drop second packet.
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(1));
|
||||||
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
|
uint16_t nack_list_size = 0;
|
||||||
|
bool extended = false;
|
||||||
|
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||||
|
EXPECT_EQ(1, nack_list_size);
|
||||||
|
ASSERT_TRUE(list != NULL);
|
||||||
|
VCMPacket packet;
|
||||||
|
stream_generator->GetPacket(&packet, 0);
|
||||||
|
EXPECT_EQ(packet.seqNum, list[0]);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TestJitterBufferNack, NormalOperation) {
|
TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||||
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
|
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
|
||||||
|
|
||||||
|
@ -353,6 +353,11 @@ int VCMSessionInfo::MakeDecodable() {
|
|||||||
return return_length;
|
return return_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VCMSessionInfo::HaveFirstPacket() const {
|
||||||
|
return !packets_.empty() && packets_.front().isFirstPacket;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VCMSessionInfo::HaveLastPacket() const {
|
VCMSessionInfo::HaveLastPacket() const {
|
||||||
return (!packets_.empty() && packets_.back().markerBit);
|
return (!packets_.empty() && packets_.back().markerBit);
|
||||||
|
@ -59,6 +59,7 @@ class VCMSessionInfo {
|
|||||||
// Returns the number of bytes deleted from the session.
|
// Returns the number of bytes deleted from the session.
|
||||||
int MakeDecodable();
|
int MakeDecodable();
|
||||||
int SessionLength() const;
|
int SessionLength() const;
|
||||||
|
bool HaveFirstPacket() const;
|
||||||
bool HaveLastPacket() const;
|
bool HaveLastPacket() const;
|
||||||
bool session_nack() const;
|
bool session_nack() const;
|
||||||
webrtc::FrameType FrameType() const { return frame_type_; }
|
webrtc::FrameType FrameType() const { return frame_type_; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user