Change JitterBuffer::GetNackList to return a std::vector<uint16_t>.
This fixed the problem with returning a pointer to an internal buffer of a JitterBuffer. R=stefan@webrtc.org BUG=none TEST=none Review URL: https://webrtc-codereview.appspot.com/53639004 Cr-Commit-Position: refs/heads/master@{#9365}
This commit is contained in:
@ -142,7 +142,6 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory)
|
||||
low_rtt_nack_threshold_ms_(-1),
|
||||
high_rtt_nack_threshold_ms_(-1),
|
||||
missing_sequence_numbers_(SequenceNumberLessThan()),
|
||||
nack_seq_nums_(),
|
||||
max_nack_list_size_(0),
|
||||
max_packet_age_to_nack_(0),
|
||||
max_incomplete_time_ms_(0),
|
||||
@ -839,7 +838,6 @@ void VCMJitterBuffer::SetNackSettings(size_t max_nack_list_size,
|
||||
max_nack_list_size_ = max_nack_list_size;
|
||||
max_packet_age_to_nack_ = max_packet_age_to_nack;
|
||||
max_incomplete_time_ms_ = max_incomplete_time_ms;
|
||||
nack_seq_nums_.resize(max_nack_list_size_);
|
||||
}
|
||||
|
||||
VCMNackMode VCMJitterBuffer::nack_mode() const {
|
||||
@ -869,13 +867,11 @@ uint16_t VCMJitterBuffer::EstimatedLowSequenceNumber(
|
||||
return frame.GetLowSeqNum() - 1;
|
||||
}
|
||||
|
||||
uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
||||
bool* request_key_frame) {
|
||||
std::vector<uint16_t> VCMJitterBuffer::GetNackList(bool* request_key_frame) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
*request_key_frame = false;
|
||||
if (nack_mode_ == kNoNack) {
|
||||
*nack_list_size = 0;
|
||||
return NULL;
|
||||
return std::vector<uint16_t>();
|
||||
}
|
||||
if (last_decoded_state_.in_initial_state()) {
|
||||
VCMFrameBuffer* next_frame = NextFrame();
|
||||
@ -894,8 +890,7 @@ uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
||||
bool found_key_frame = RecycleFramesUntilKeyFrame();
|
||||
if (!found_key_frame) {
|
||||
*request_key_frame = have_non_empty_frame;
|
||||
*nack_list_size = 0;
|
||||
return NULL;
|
||||
return std::vector<uint16_t>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -914,8 +909,7 @@ uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
||||
if (rit == incomplete_frames_.rend()) {
|
||||
// Request a key frame if we don't have one already.
|
||||
*request_key_frame = true;
|
||||
*nack_list_size = 0;
|
||||
return NULL;
|
||||
return std::vector<uint16_t>();
|
||||
} else {
|
||||
// Skip to the last key frame. If it's incomplete we will start
|
||||
// NACKing it.
|
||||
@ -926,13 +920,9 @@ uint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned int i = 0;
|
||||
SequenceNumberSet::iterator it = missing_sequence_numbers_.begin();
|
||||
for (; it != missing_sequence_numbers_.end(); ++it, ++i) {
|
||||
nack_seq_nums_[i] = *it;
|
||||
}
|
||||
*nack_list_size = i;
|
||||
return &nack_seq_nums_[0];
|
||||
std::vector<uint16_t> nack_list(missing_sequence_numbers_.begin(),
|
||||
missing_sequence_numbers_.end());
|
||||
return nack_list;
|
||||
}
|
||||
|
||||
void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) {
|
||||
|
||||
@ -172,9 +172,7 @@ class VCMJitterBuffer {
|
||||
VCMNackMode nack_mode() const;
|
||||
|
||||
// Returns a list of the sequence numbers currently missing.
|
||||
// WARNING: GetNackList() returns a pointer to an internal buffer that is only
|
||||
// valid until the next GetNackList() call.
|
||||
uint16_t* GetNackList(uint16_t* nack_list_size, bool* request_key_frame);
|
||||
std::vector<uint16_t> GetNackList(bool* request_key_frame);
|
||||
|
||||
// Set decode error mode - Should not be changed in the middle of the
|
||||
// session. Changes will not influence frames already in the buffer.
|
||||
@ -348,7 +346,6 @@ class VCMJitterBuffer {
|
||||
// Holds the internal NACK list (the missing sequence numbers).
|
||||
SequenceNumberSet missing_sequence_numbers_;
|
||||
uint16_t latest_received_sequence_number_;
|
||||
std::vector<uint16_t> nack_seq_nums_;
|
||||
size_t max_nack_list_size_;
|
||||
int max_packet_age_to_nack_; // Measured in sequence numbers.
|
||||
int max_incomplete_time_ms_;
|
||||
|
||||
@ -1910,21 +1910,14 @@ TEST_F(TestJitterBufferNack, NackTooOldPackets) {
|
||||
kVideoFrameDelta));
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
|
||||
uint16_t nack_list_length = max_nack_list_size_;
|
||||
bool request_key_frame = false;
|
||||
uint16_t* nack_list = jitter_buffer_->GetNackList(&nack_list_length,
|
||||
&request_key_frame);
|
||||
std::vector<uint16_t> nack_list =
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// No key frame will be requested since the jitter buffer is empty.
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
EXPECT_TRUE(nack_list == NULL);
|
||||
EXPECT_EQ(0, nack_list_length);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
|
||||
EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError);
|
||||
// Verify that the jitter buffer requests a key frame since we need one to
|
||||
// start decoding.
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
EXPECT_TRUE(nack_list == NULL);
|
||||
EXPECT_EQ(0, nack_list_length);
|
||||
// Waiting for a key frame.
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeIncompleteFrame());
|
||||
@ -1945,13 +1938,13 @@ TEST_F(TestJitterBufferNack, NackLargeJitterBuffer) {
|
||||
// Insert a frame which should trigger a recycle until the next key frame.
|
||||
EXPECT_GE(InsertFrames(oldest_packet_to_nack_, kVideoFrameDelta), kNoError);
|
||||
|
||||
uint16_t nack_list_length = max_nack_list_size_;
|
||||
bool request_key_frame = false;
|
||||
jitter_buffer_->GetNackList(&nack_list_length, &request_key_frame);
|
||||
std::vector<uint16_t> nack_list =
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// Verify that the jitter buffer does not request a key frame.
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
// Verify that no packets are NACKed.
|
||||
EXPECT_EQ(0, nack_list_length);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
// Verify that we can decode the next frame.
|
||||
EXPECT_TRUE(DecodeCompleteFrame());
|
||||
}
|
||||
@ -1967,9 +1960,8 @@ TEST_F(TestJitterBufferNack, NackListFull) {
|
||||
EXPECT_EQ(kFlushIndicator, InsertFrame(kVideoFrameDelta));
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
|
||||
uint16_t nack_list_length = max_nack_list_size_;
|
||||
bool request_key_frame = false;
|
||||
jitter_buffer_->GetNackList(&nack_list_length, &request_key_frame);
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// The jitter buffer is empty, so we won't request key frames until we get a
|
||||
// packet.
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
@ -1977,7 +1969,7 @@ TEST_F(TestJitterBufferNack, NackListFull) {
|
||||
EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError);
|
||||
// Now we have a packet in the jitter buffer, a key frame will be requested
|
||||
// since it's not a key frame.
|
||||
jitter_buffer_->GetNackList(&nack_list_length, &request_key_frame);
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// The jitter buffer is empty, so we won't request key frames until we get a
|
||||
// packet.
|
||||
EXPECT_TRUE(request_key_frame);
|
||||
@ -1994,13 +1986,11 @@ TEST_F(TestJitterBufferNack, NoNackListReturnedBeforeFirstDecode) {
|
||||
DropFrame(10);
|
||||
// Insert a frame and try to generate a NACK list. Shouldn't get one.
|
||||
EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError);
|
||||
uint16_t nack_list_size = 0;
|
||||
bool request_key_frame = false;
|
||||
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size,
|
||||
&request_key_frame);
|
||||
std::vector<uint16_t> nack_list =
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// No list generated, and a key frame request is signaled.
|
||||
EXPECT_TRUE(list == NULL);
|
||||
EXPECT_EQ(0, nack_list_size);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
EXPECT_TRUE(request_key_frame);
|
||||
}
|
||||
|
||||
@ -2012,11 +2002,9 @@ TEST_F(TestJitterBufferNack, NackListBuiltBeforeFirstDecode) {
|
||||
stream_generator_->NextPacket(NULL); // Drop packet.
|
||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||
EXPECT_TRUE(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);
|
||||
EXPECT_TRUE(list != NULL);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(1u, nack_list.size());
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, VerifyRetransmittedFlag) {
|
||||
@ -2033,13 +2021,11 @@ TEST_F(TestJitterBufferNack, VerifyRetransmittedFlag) {
|
||||
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(packet, &retransmitted));
|
||||
EXPECT_FALSE(retransmitted);
|
||||
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);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(1u, nack_list.size());
|
||||
stream_generator_->PopPacket(&packet, 0);
|
||||
EXPECT_EQ(packet.seqNum, list[0]);
|
||||
EXPECT_EQ(packet.seqNum, nack_list[0]);
|
||||
EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(packet,
|
||||
&retransmitted));
|
||||
EXPECT_TRUE(retransmitted);
|
||||
@ -2054,14 +2040,12 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrame) {
|
||||
// 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);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(1u, nack_list.size());
|
||||
VCMPacket packet;
|
||||
stream_generator_->GetPacket(&packet, 0);
|
||||
EXPECT_EQ(packet.seqNum, list[0]);
|
||||
EXPECT_EQ(packet.seqNum, nack_list[0]);
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
|
||||
@ -2081,13 +2065,11 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
|
||||
// Drop second packet in frame.
|
||||
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);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(1u, nack_list.size());
|
||||
stream_generator_->GetPacket(&packet, 0);
|
||||
EXPECT_EQ(packet.seqNum, list[0]);
|
||||
EXPECT_EQ(packet.seqNum, nack_list[0]);
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||
@ -2117,15 +2099,14 @@ TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||
EXPECT_EQ(0, stream_generator_->PacketsRemaining());
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeIncompleteFrame());
|
||||
uint16_t nack_list_size = 0;
|
||||
bool request_key_frame = false;
|
||||
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size,
|
||||
&request_key_frame);
|
||||
std::vector<uint16_t> nack_list =
|
||||
jitter_buffer_->GetNackList(&request_key_frame);
|
||||
// Verify the NACK list.
|
||||
const int kExpectedNackSize = 9;
|
||||
ASSERT_EQ(kExpectedNackSize, nack_list_size);
|
||||
for (int i = 0; i < nack_list_size; ++i)
|
||||
EXPECT_EQ((1 + i) * 10, list[i]);
|
||||
const size_t kExpectedNackSize = 9;
|
||||
ASSERT_EQ(kExpectedNackSize, nack_list.size());
|
||||
for (size_t i = 0; i < nack_list.size(); ++i)
|
||||
EXPECT_EQ((1 + i) * 10, nack_list[i]);
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, NormalOperationWrap) {
|
||||
@ -2153,14 +2134,13 @@ TEST_F(TestJitterBufferNack, NormalOperationWrap) {
|
||||
EXPECT_EQ(0, stream_generator_->PacketsRemaining());
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
uint16_t nack_list_size = 0;
|
||||
bool extended = false;
|
||||
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
// Verify the NACK list.
|
||||
const int kExpectedNackSize = 10;
|
||||
ASSERT_EQ(kExpectedNackSize, nack_list_size);
|
||||
for (int i = 0; i < nack_list_size; ++i)
|
||||
EXPECT_EQ(i * 10, list[i]);
|
||||
const size_t kExpectedNackSize = 10;
|
||||
ASSERT_EQ(kExpectedNackSize, nack_list.size());
|
||||
for (size_t i = 0; i < nack_list.size(); ++i)
|
||||
EXPECT_EQ(i * 10, nack_list[i]);
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, NormalOperationWrap2) {
|
||||
@ -2188,22 +2168,20 @@ TEST_F(TestJitterBufferNack, NormalOperationWrap2) {
|
||||
}
|
||||
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(0));
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
uint16_t nack_list_size = 0;
|
||||
bool extended = false;
|
||||
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
// Verify the NACK list.
|
||||
ASSERT_EQ(1, nack_list_size);
|
||||
EXPECT_EQ(65535, list[0]);
|
||||
ASSERT_EQ(1u, nack_list.size());
|
||||
EXPECT_EQ(65535, nack_list[0]);
|
||||
}
|
||||
|
||||
TEST_F(TestJitterBufferNack, ResetByFutureKeyFrameDoesntError) {
|
||||
stream_generator_->Init(0, 0, clock_->TimeInMilliseconds());
|
||||
InsertFrame(kVideoFrameKey);
|
||||
EXPECT_TRUE(DecodeCompleteFrame());
|
||||
uint16_t nack_list_size = 0;
|
||||
bool extended = false;
|
||||
jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||
EXPECT_EQ(0, nack_list_size);
|
||||
std::vector<uint16_t> nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
|
||||
// Far-into-the-future video frame, could be caused by resetting the encoder
|
||||
// or otherwise restarting. This should not fail when error when the packet is
|
||||
@ -2212,15 +2190,15 @@ TEST_F(TestJitterBufferNack, ResetByFutureKeyFrameDoesntError) {
|
||||
clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
|
||||
InsertFrame(kVideoFrameKey);
|
||||
EXPECT_TRUE(DecodeCompleteFrame());
|
||||
jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||
EXPECT_EQ(0, nack_list_size);
|
||||
nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
|
||||
// Stream should be decodable from this point.
|
||||
clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
|
||||
InsertFrame(kVideoFrameDelta);
|
||||
EXPECT_TRUE(DecodeCompleteFrame());
|
||||
jitter_buffer_->GetNackList(&nack_list_size, &extended);
|
||||
EXPECT_EQ(0, nack_list_size);
|
||||
nack_list = jitter_buffer_->GetNackList(&extended);
|
||||
EXPECT_EQ(0u, nack_list.size());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -209,23 +209,8 @@ VCMNackMode VCMReceiver::NackMode() const {
|
||||
return jitter_buffer_.nack_mode();
|
||||
}
|
||||
|
||||
VCMNackStatus VCMReceiver::NackList(uint16_t* nack_list,
|
||||
uint16_t size,
|
||||
uint16_t* nack_list_length) {
|
||||
bool request_key_frame = false;
|
||||
uint16_t* internal_nack_list = jitter_buffer_.GetNackList(
|
||||
nack_list_length, &request_key_frame);
|
||||
assert(*nack_list_length <= size);
|
||||
if (*nack_list_length > size) {
|
||||
*nack_list_length = size;
|
||||
}
|
||||
if (internal_nack_list != NULL && *nack_list_length > 0) {
|
||||
memcpy(nack_list, internal_nack_list, *nack_list_length * sizeof(uint16_t));
|
||||
}
|
||||
if (request_key_frame) {
|
||||
return kNackKeyFrameRequest;
|
||||
}
|
||||
return kNackOk;
|
||||
std::vector<uint16_t> VCMReceiver::NackList(bool* request_key_frame) {
|
||||
return jitter_buffer_.GetNackList(request_key_frame);
|
||||
}
|
||||
|
||||
void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
|
||||
|
||||
@ -23,11 +23,6 @@ namespace webrtc {
|
||||
class Clock;
|
||||
class VCMEncodedFrame;
|
||||
|
||||
enum VCMNackStatus {
|
||||
kNackOk,
|
||||
kNackKeyFrameRequest
|
||||
};
|
||||
|
||||
class VCMReceiver {
|
||||
public:
|
||||
VCMReceiver(VCMTiming* timing,
|
||||
@ -55,8 +50,7 @@ class VCMReceiver {
|
||||
int max_packet_age_to_nack,
|
||||
int max_incomplete_time_ms);
|
||||
VCMNackMode NackMode() const;
|
||||
VCMNackStatus NackList(uint16_t* nackList, uint16_t size,
|
||||
uint16_t* nack_list_length);
|
||||
std::vector<uint16_t> NackList(bool* request_key_frame);
|
||||
|
||||
// Receiver video delay.
|
||||
int SetMinReceiverDelay(int desired_delay_ms);
|
||||
|
||||
@ -163,11 +163,9 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
|
||||
// Advance time until it's time to decode the key frame.
|
||||
clock_->AdvanceTimeMilliseconds(kMinDelayMs);
|
||||
EXPECT_TRUE(DecodeNextFrame());
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackOk, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
}
|
||||
|
||||
TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
|
||||
@ -182,11 +180,9 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
|
||||
for (int i = 0; i < kNumFrames; ++i) {
|
||||
EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
|
||||
}
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackKeyFrameRequest, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_TRUE(request_key_frame);
|
||||
}
|
||||
|
||||
TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
|
||||
@ -215,11 +211,9 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
|
||||
key_frame_inserted);
|
||||
EXPECT_TRUE(DecodeNextFrame());
|
||||
// Make sure we get a key frame request.
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackKeyFrameRequest, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_TRUE(request_key_frame);
|
||||
}
|
||||
|
||||
TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
|
||||
@ -250,11 +244,9 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
|
||||
EXPECT_TRUE(DecodeNextFrame());
|
||||
// Make sure we don't get a key frame request since we haven't generated
|
||||
// enough frames.
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackOk, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
}
|
||||
|
||||
TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
|
||||
@ -285,11 +277,9 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
|
||||
EXPECT_TRUE(DecodeNextFrame());
|
||||
// Make sure we don't get a key frame request since the non-decodable duration
|
||||
// is only one frame.
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackOk, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
}
|
||||
|
||||
TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
|
||||
@ -320,10 +310,8 @@ TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
|
||||
EXPECT_TRUE(DecodeNextFrame());
|
||||
// Make sure we don't get a key frame request since we have a key frame
|
||||
// in the list.
|
||||
uint16_t nack_list[kMaxNackListSize];
|
||||
uint16_t nack_list_length = 0;
|
||||
VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
|
||||
&nack_list_length);
|
||||
EXPECT_EQ(kNackOk, ret);
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
|
||||
EXPECT_FALSE(request_key_frame);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -194,7 +194,6 @@ class VideoReceiver {
|
||||
EXCLUSIVE_LOCKS_REQUIRED(_receiveCritSect);
|
||||
int32_t RequestKeyFrame();
|
||||
int32_t RequestSliceLossIndication(const uint64_t pictureID) const;
|
||||
int32_t NackList(uint16_t* nackList, uint16_t* size);
|
||||
|
||||
private:
|
||||
enum VCMKeyRequestMode {
|
||||
|
||||
@ -136,15 +136,20 @@ int32_t VideoReceiver::Process() {
|
||||
callback_registered = _packetRequestCallback != NULL;
|
||||
}
|
||||
if (callback_registered && length > 0) {
|
||||
std::vector<uint16_t> nackList(length);
|
||||
const int32_t ret = NackList(&nackList[0], &length);
|
||||
if (ret != VCM_OK && returnValue == VCM_OK) {
|
||||
returnValue = ret;
|
||||
// Collect sequence numbers from the default receiver.
|
||||
bool request_key_frame = false;
|
||||
std::vector<uint16_t> nackList = _receiver.NackList(&request_key_frame);
|
||||
int32_t ret = VCM_OK;
|
||||
if (request_key_frame) {
|
||||
ret = RequestKeyFrame();
|
||||
if (ret != VCM_OK && returnValue == VCM_OK) {
|
||||
returnValue = ret;
|
||||
}
|
||||
}
|
||||
if (ret == VCM_OK && length > 0) {
|
||||
if (ret == VCM_OK && !nackList.empty()) {
|
||||
CriticalSectionScoped cs(process_crit_sect_.get());
|
||||
if (_packetRequestCallback != NULL) {
|
||||
_packetRequestCallback->ResendPackets(&nackList[0], length);
|
||||
_packetRequestCallback->ResendPackets(&nackList[0], nackList.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -549,22 +554,6 @@ int32_t VideoReceiver::SetRenderDelay(uint32_t timeMS) {
|
||||
// Current video delay
|
||||
int32_t VideoReceiver::Delay() const { return _timing.TargetVideoDelay(); }
|
||||
|
||||
// Nack list
|
||||
int32_t VideoReceiver::NackList(uint16_t* nackList, uint16_t* size) {
|
||||
VCMNackStatus nackStatus = kNackOk;
|
||||
uint16_t nack_list_length = 0;
|
||||
// Collect sequence numbers from the default receiver
|
||||
// if in normal nack mode.
|
||||
if (_receiver.NackMode() != kNoNack) {
|
||||
nackStatus = _receiver.NackList(nackList, *size, &nack_list_length);
|
||||
}
|
||||
*size = nack_list_length;
|
||||
if (nackStatus == kNackKeyFrameRequest) {
|
||||
return RequestKeyFrame();
|
||||
}
|
||||
return VCM_OK;
|
||||
}
|
||||
|
||||
uint32_t VideoReceiver::DiscardedPackets() const {
|
||||
return _receiver.DiscardedPackets();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user