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}
diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.cc b/webrtc/modules/video_coding/main/source/jitter_buffer.cc
index 686b182..9092a65 100644
--- a/webrtc/modules/video_coding/main/source/jitter_buffer.cc
+++ b/webrtc/modules/video_coding/main/source/jitter_buffer.cc
@@ -142,7 +142,6 @@
       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 @@
   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 @@
   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 @@
       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 @@
       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 @@
       }
     }
   }
-  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) {
diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.h b/webrtc/modules/video_coding/main/source/jitter_buffer.h
index c1f9aab..686ec04 100644
--- a/webrtc/modules/video_coding/main/source/jitter_buffer.h
+++ b/webrtc/modules/video_coding/main/source/jitter_buffer.h
@@ -172,9 +172,7 @@
   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 @@
   // 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_;
diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
index 36abf6d..b5f8b95 100644
--- a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
+++ b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
@@ -1910,21 +1910,14 @@
                                           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 @@
   // 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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   // 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 @@
   // 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 @@
   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 @@
   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 @@
   }
   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 @@
   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
diff --git a/webrtc/modules/video_coding/main/source/receiver.cc b/webrtc/modules/video_coding/main/source/receiver.cc
index a2bfae6..fbd1fee 100644
--- a/webrtc/modules/video_coding/main/source/receiver.cc
+++ b/webrtc/modules/video_coding/main/source/receiver.cc
@@ -209,23 +209,8 @@
   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) {
diff --git a/webrtc/modules/video_coding/main/source/receiver.h b/webrtc/modules/video_coding/main/source/receiver.h
index 049fb84..efd66bc 100644
--- a/webrtc/modules/video_coding/main/source/receiver.h
+++ b/webrtc/modules/video_coding/main/source/receiver.h
@@ -23,11 +23,6 @@
 class Clock;
 class VCMEncodedFrame;
 
-enum VCMNackStatus {
-  kNackOk,
-  kNackKeyFrameRequest
-};
-
 class VCMReceiver {
  public:
   VCMReceiver(VCMTiming* timing,
@@ -55,8 +50,7 @@
                        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);
diff --git a/webrtc/modules/video_coding/main/source/receiver_unittest.cc b/webrtc/modules/video_coding/main/source/receiver_unittest.cc
index 84a9527..6365ab3 100644
--- a/webrtc/modules/video_coding/main/source/receiver_unittest.cc
+++ b/webrtc/modules/video_coding/main/source/receiver_unittest.cc
@@ -163,11 +163,9 @@
   // 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 @@
   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 @@
       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 @@
   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 @@
   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 @@
   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
diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h
index a3ec715..c8f8221 100644
--- a/webrtc/modules/video_coding/main/source/video_coding_impl.h
+++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h
@@ -194,7 +194,6 @@
       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 {
diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc
index 32fe1a9..08e6208 100644
--- a/webrtc/modules/video_coding/main/source/video_receiver.cc
+++ b/webrtc/modules/video_coding/main/source/video_receiver.cc
@@ -136,15 +136,20 @@
       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 @@
 // 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();
 }