/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "modules/video_coding/main/source/jitter_buffer.h"

#include <algorithm>
#include <cassert>

#include "modules/video_coding/main/source/event.h"
#include "modules/video_coding/main/source/frame_buffer.h"
#include "modules/video_coding/main/source/inter_frame_delay.h"
#include "modules/video_coding/main/source/internal_defines.h"
#include "modules/video_coding/main/source/jitter_buffer_common.h"
#include "modules/video_coding/main/source/jitter_estimator.h"
#include "modules/video_coding/main/source/packet.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/trace.h"

namespace webrtc {

// Predicates used when searching for frames in the frame buffer list
class FrameSmallerTimestamp {
 public:
  explicit FrameSmallerTimestamp(uint32_t timestamp) : timestamp_(timestamp) {}
  bool operator()(VCMFrameBuffer* frame) {
    return (LatestTimestamp(timestamp_, frame->TimeStamp(), NULL) ==
            timestamp_);
  }

 private:
  uint32_t timestamp_;
};

class FrameEqualTimestamp {
 public:
  explicit FrameEqualTimestamp(uint32_t timestamp) : timestamp_(timestamp) {}
  bool operator()(VCMFrameBuffer* frame) {
    return (timestamp_ == frame->TimeStamp());
  }

 private:
  uint32_t timestamp_;
};

class CompleteDecodableKeyFrameCriteria {
 public:
  bool operator()(VCMFrameBuffer* frame) {
    return (frame->FrameType() == kVideoFrameKey) &&
           (frame->GetState() == kStateComplete ||
            frame->GetState() == kStateDecodable);
  }
};

VCMJitterBuffer::VCMJitterBuffer(TickTimeBase* clock,
                                 int vcm_id,
                                 int receiver_id,
                                 bool master)
    : vcm_id_(vcm_id),
      receiver_id_(receiver_id),
      clock_(clock),
      running_(false),
      crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
      master_(master),
      frame_event_(),
      packet_event_(),
      max_number_of_frames_(kStartNumberOfFrames),
      frame_buffers_(),
      frame_list_(),
      last_decoded_state_(),
      first_packet_(true),
      num_not_decodable_packets_(0),
      receive_statistics_(),
      incoming_frame_rate_(0),
      incoming_frame_count_(0),
      time_last_incoming_frame_count_(0),
      incoming_bit_count_(0),
      incoming_bit_rate_(0),
      drop_count_(0),
      num_consecutive_old_frames_(0),
      num_consecutive_old_packets_(0),
      num_discarded_packets_(0),
      jitter_estimate_(vcm_id, receiver_id),
      inter_frame_delay_(clock_->MillisecondTimestamp()),
      rtt_ms_(0),
      nack_mode_(kNoNack),
      low_rtt_nack_threshold_ms_(-1),
      high_rtt_nack_threshold_ms_(-1),
      nack_seq_nums_(),
      nack_seq_nums_length_(0),
      waiting_for_key_frame_(false) {
  memset(frame_buffers_, 0, sizeof(frame_buffers_));
  memset(receive_statistics_, 0, sizeof(receive_statistics_));
  memset(nack_seq_nums_internal_, -1, sizeof(nack_seq_nums_internal_));

  for (int i = 0; i < kStartNumberOfFrames; i++) {
    frame_buffers_[i] = new VCMFrameBuffer();
  }
}

VCMJitterBuffer::~VCMJitterBuffer() {
  Stop();
  for (int i = 0; i < kMaxNumberOfFrames; i++) {
    if (frame_buffers_[i]) {
      delete frame_buffers_[i];
    }
  }
  delete crit_sect_;
}

void VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs) {
  if (this != &rhs) {
    crit_sect_->Enter();
    rhs.crit_sect_->Enter();
    vcm_id_ = rhs.vcm_id_;
    receiver_id_ = rhs.receiver_id_;
    running_ = rhs.running_;
    master_ = !rhs.master_;
    max_number_of_frames_ = rhs.max_number_of_frames_;
    incoming_frame_rate_ = rhs.incoming_frame_rate_;
    incoming_frame_count_ = rhs.incoming_frame_count_;
    time_last_incoming_frame_count_ = rhs.time_last_incoming_frame_count_;
    incoming_bit_count_ = rhs.incoming_bit_count_;
    incoming_bit_rate_ = rhs.incoming_bit_rate_;
    drop_count_ = rhs.drop_count_;
    num_consecutive_old_frames_ = rhs.num_consecutive_old_frames_;
    num_consecutive_old_packets_ = rhs.num_consecutive_old_packets_;
    num_discarded_packets_ = rhs.num_discarded_packets_;
    jitter_estimate_ = rhs.jitter_estimate_;
    inter_frame_delay_ = rhs.inter_frame_delay_;
    waiting_for_completion_ = rhs.waiting_for_completion_;
    rtt_ms_ = rhs.rtt_ms_;
    nack_seq_nums_length_ = rhs.nack_seq_nums_length_;
    waiting_for_key_frame_ = rhs.waiting_for_key_frame_;
    first_packet_ = rhs.first_packet_;
    last_decoded_state_ =  rhs.last_decoded_state_;
    num_not_decodable_packets_ = rhs.num_not_decodable_packets_;
    memcpy(receive_statistics_, rhs.receive_statistics_,
           sizeof(receive_statistics_));
    memcpy(nack_seq_nums_internal_, rhs.nack_seq_nums_internal_,
           sizeof(nack_seq_nums_internal_));
    memcpy(nack_seq_nums_, rhs.nack_seq_nums_, sizeof(nack_seq_nums_));
    for (int i = 0; i < kMaxNumberOfFrames; i++) {
      if (frame_buffers_[i] != NULL) {
        delete frame_buffers_[i];
        frame_buffers_[i] = NULL;
      }
    }
    frame_list_.clear();
    for (int i = 0; i < max_number_of_frames_; i++) {
      frame_buffers_[i] = new VCMFrameBuffer(*(rhs.frame_buffers_[i]));
      if (frame_buffers_[i]->Length() > 0) {
        FrameList::reverse_iterator rit = std::find_if(
            frame_list_.rbegin(), frame_list_.rend(),
            FrameSmallerTimestamp(frame_buffers_[i]->TimeStamp()));
        frame_list_.insert(rit.base(), frame_buffers_[i]);
      }
    }
    rhs.crit_sect_->Leave();
    crit_sect_->Leave();
  }
}

void VCMJitterBuffer::Start() {
  CriticalSectionScoped cs(crit_sect_);
  running_ = true;
  incoming_frame_count_ = 0;
  incoming_frame_rate_ = 0;
  incoming_bit_count_ = 0;
  incoming_bit_rate_ = 0;
  time_last_incoming_frame_count_ = clock_->MillisecondTimestamp();
  memset(receive_statistics_, 0, sizeof(receive_statistics_));

  num_consecutive_old_frames_ = 0;
  num_consecutive_old_packets_ = 0;
  num_discarded_packets_ = 0;

  // Start in a non-signaled state.
  frame_event_.Reset();
  packet_event_.Reset();
  waiting_for_completion_.frame_size = 0;
  waiting_for_completion_.timestamp = 0;
  waiting_for_completion_.latest_packet_time = -1;
  first_packet_ = true;
  nack_seq_nums_length_ = 0;
  waiting_for_key_frame_ = false;
  rtt_ms_ = 0;
  num_not_decodable_packets_ = 0;

  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
               VCMId(vcm_id_, receiver_id_), "JB(0x%x): Jitter buffer: start",
               this);
}

void VCMJitterBuffer::Stop() {
  crit_sect_->Enter();
  running_ = false;
  last_decoded_state_.Reset();
  frame_list_.clear();
  for (int i = 0; i < kMaxNumberOfFrames; i++) {
    if (frame_buffers_[i] != NULL) {
      static_cast<VCMFrameBuffer*>(frame_buffers_[i])->SetState(kStateFree);
    }
  }

  crit_sect_->Leave();
  // Make sure we wake up any threads waiting on these events.
  frame_event_.Set();
  packet_event_.Set();
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
               VCMId(vcm_id_, receiver_id_), "JB(0x%x): Jitter buffer: stop",
               this);
}

bool VCMJitterBuffer::Running() const {
  CriticalSectionScoped cs(crit_sect_);
  return running_;
}

void VCMJitterBuffer::Flush() {
  CriticalSectionScoped cs(crit_sect_);
  // Erase all frames from the sorted list and set their state to free.
  frame_list_.clear();
  for (int i = 0; i < max_number_of_frames_; i++) {
    ReleaseFrameIfNotDecoding(frame_buffers_[i]);
  }
  last_decoded_state_.Reset();  // TODO(mikhal): sync reset.
  num_not_decodable_packets_ = 0;
  frame_event_.Reset();
  packet_event_.Reset();
  num_consecutive_old_frames_ = 0;
  num_consecutive_old_packets_ = 0;
  // Also reset the jitter and delay estimates
  jitter_estimate_.Reset();
  inter_frame_delay_.Reset(clock_->MillisecondTimestamp());
  waiting_for_completion_.frame_size = 0;
  waiting_for_completion_.timestamp = 0;
  waiting_for_completion_.latest_packet_time = -1;
  first_packet_ = true;
  nack_seq_nums_length_ = 0;
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
               VCMId(vcm_id_, receiver_id_), "JB(0x%x): Jitter buffer: flush",
               this);
}

// Get received key and delta frames
void VCMJitterBuffer::FrameStatistics(uint32_t* received_delta_frames,
                                      uint32_t* received_key_frames) const {
  assert(received_delta_frames);
  assert(received_key_frames);
  CriticalSectionScoped cs(crit_sect_);
  *received_delta_frames = receive_statistics_[1] + receive_statistics_[3];
  *received_key_frames = receive_statistics_[0] + receive_statistics_[2];
}

int VCMJitterBuffer::num_not_decodable_packets() const {
  CriticalSectionScoped cs(crit_sect_);
  return num_not_decodable_packets_;
}

int VCMJitterBuffer::num_discarded_packets() const {
  CriticalSectionScoped cs(crit_sect_);
  return num_discarded_packets_;
}

// Calculate framerate and bitrate.
void VCMJitterBuffer::IncomingRateStatistics(unsigned int* framerate,
                                             unsigned int* bitrate) {
  assert(framerate);
  assert(bitrate);
  CriticalSectionScoped cs(crit_sect_);
  const int64_t now = clock_->MillisecondTimestamp();
  int64_t diff = now - time_last_incoming_frame_count_;
  if (diff < 1000 && incoming_frame_rate_ > 0 && incoming_bit_rate_ > 0) {
    // Make sure we report something even though less than
    // 1 second has passed since last update.
    *framerate = incoming_frame_rate_;
    *bitrate = incoming_bit_rate_;
  } else if (incoming_frame_count_ != 0) {
    // We have received frame(s) since last call to this function

    // Prepare calculations
    if (diff <= 0) {
      diff = 1;
    }
    // we add 0.5f for rounding
    float rate = 0.5f + ((incoming_frame_count_ * 1000.0f) / diff);
    if (rate < 1.0f) {
      rate = 1.0f;
    }

    // Calculate frame rate
    // Let r be rate.
    // r(0) = 1000*framecount/delta_time.
    // (I.e. frames per second since last calculation.)
    // frame_rate = r(0)/2 + r(-1)/2
    // (I.e. fr/s average this and the previous calculation.)
    *framerate = (incoming_frame_rate_ + static_cast<unsigned int>(rate)) / 2;
    incoming_frame_rate_ = static_cast<unsigned int>(rate);

    // Calculate bit rate
    if (incoming_bit_count_ == 0) {
      *bitrate = 0;
    } else {
      *bitrate = 10 * ((100 * incoming_bit_count_) /
                       static_cast<unsigned int>(diff));
    }
    incoming_bit_rate_ = *bitrate;

    // Reset count
    incoming_frame_count_ = 0;
    incoming_bit_count_ = 0;
    time_last_incoming_frame_count_ = now;

  } else {
    // No frames since last call
    time_last_incoming_frame_count_ = clock_->MillisecondTimestamp();
    *framerate = 0;
    bitrate = 0;
    incoming_bit_rate_ = 0;
  }
}

// Wait for the first packet in the next frame to arrive.
int64_t VCMJitterBuffer::NextTimestamp(uint32_t max_wait_time_ms,
                                       FrameType* incoming_frame_type,
                                       int64_t* render_time_ms) {
  assert(incoming_frame_type);
  assert(render_time_ms);
  if (!running_) {
    return -1;
  }

  crit_sect_->Enter();

  // Finding oldest frame ready for decoder, check sequence number and size.
  CleanUpOldFrames();

  FrameList::iterator it = frame_list_.begin();

  if (it == frame_list_.end()) {
    packet_event_.Reset();
    crit_sect_->Leave();

    if (packet_event_.Wait(max_wait_time_ms) == kEventSignaled) {
      // are we closing down the Jitter buffer
      if (!running_) {
        return -1;
      }
      crit_sect_->Enter();

      CleanUpOldFrames();
      it = frame_list_.begin();
    } else {
      crit_sect_->Enter();
    }
  }

  if (it == frame_list_.end()) {
    crit_sect_->Leave();
    return -1;
  }
  // We have a frame.
  *incoming_frame_type = (*it)->FrameType();
  *render_time_ms = (*it)->RenderTimeMs();
  const uint32_t timestamp = (*it)->TimeStamp();
  crit_sect_->Leave();

  return timestamp;
}

// Answers the question:
// Will the packet sequence be complete if the next frame is grabbed for
// decoding right now? That is, have we lost a frame between the last decoded
// frame and the next, or is the next
// frame missing one or more packets?
bool VCMJitterBuffer::CompleteSequenceWithNextFrame() {
  CriticalSectionScoped cs(crit_sect_);
  // Finding oldest frame ready for decoder, check sequence number and size
  CleanUpOldFrames();

  if (frame_list_.empty())
    return true;

  VCMFrameBuffer* oldest_frame = frame_list_.front();
  if (frame_list_.size() <= 1 &&
      oldest_frame->GetState() != kStateComplete) {
    // Frame not ready to be decoded.
    return true;
  }
  if (!oldest_frame->Complete()) {
    return false;
  }

  // See if we have lost a frame before this one.
  if (last_decoded_state_.init()) {
    // Following start, reset or flush -> check for key frame.
    if (oldest_frame->FrameType() != kVideoFrameKey) {
      return false;
    }
  } else if (oldest_frame->GetLowSeqNum() == -1) {
    return false;
  } else if (!last_decoded_state_.ContinuousFrame(oldest_frame)) {
    return false;
  }
  return true;
}

// Returns immediately or a |max_wait_time_ms| ms event hang waiting for a
// complete frame, |max_wait_time_ms| decided by caller.
VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
    uint32_t max_wait_time_ms) {
  if (!running_) {
    return NULL;
  }

  crit_sect_->Enter();

  CleanUpOldFrames();

  if (last_decoded_state_.init() && WaitForRetransmissions()) {
    waiting_for_key_frame_ = true;
  }

  FrameList::iterator it = FindOldestCompleteContinuousFrame(false);
  if (it == frame_list_.end()) {
    if (max_wait_time_ms == 0) {
      crit_sect_->Leave();
      return NULL;
    }
    const int64_t end_wait_time_ms = clock_->MillisecondTimestamp()
                                           + max_wait_time_ms;
    int64_t wait_time_ms = max_wait_time_ms;
    while (wait_time_ms > 0) {
      crit_sect_->Leave();
      const EventTypeWrapper ret =
        frame_event_.Wait(static_cast<uint32_t>(wait_time_ms));
      crit_sect_->Enter();
      if (ret == kEventSignaled) {
        // are we closing down the Jitter buffer
        if (!running_) {
          crit_sect_->Leave();
          return NULL;
        }

        // Finding oldest frame ready for decoder, but check
        // sequence number and size
        CleanUpOldFrames();
        it = FindOldestCompleteContinuousFrame(false);
        if (it == frame_list_.end()) {
          wait_time_ms = end_wait_time_ms -
                         clock_->MillisecondTimestamp();
        } else {
          break;
        }
      } else {
        crit_sect_->Leave();
        return NULL;
      }
    }
    // Inside |crit_sect_|.
  } else {
    // We already have a frame reset the event.
    frame_event_.Reset();
  }

  if (it == frame_list_.end()) {
    // Even after signaling we're still missing a complete continuous frame.
    crit_sect_->Leave();
    return NULL;
  }

  VCMFrameBuffer* oldest_frame = *it;
  it = frame_list_.erase(it);

  // Update jitter estimate.
  const bool retransmitted = (oldest_frame->GetNackCount() > 0);
  if (retransmitted) {
    jitter_estimate_.FrameNacked();
  } else if (oldest_frame->Length() > 0) {
    // Ignore retransmitted and empty frames.
    UpdateJitterEstimate(*oldest_frame, false);
  }

  oldest_frame->SetState(kStateDecoding);

  CleanUpOldFrames();

  if (oldest_frame->FrameType() == kVideoFrameKey) {
    waiting_for_key_frame_ = false;
  }

  // We have a frame - update decoded state with frame info.
  last_decoded_state_.SetState(oldest_frame);

  crit_sect_->Leave();

  return oldest_frame;
}

VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecoding() {
  CriticalSectionScoped cs(crit_sect_);
  if (!running_) {
    return NULL;
  }

  if (WaitForRetransmissions()) {
    return GetFrameForDecodingNACK();
  }

  CleanUpOldFrames();

  if (frame_list_.empty()) {
    return NULL;
  }

  VCMFrameBuffer* oldest_frame = frame_list_.front();
  if (frame_list_.size() <= 1 &&
      oldest_frame->GetState() != kStateComplete) {
    return NULL;
  }

  // Incomplete frame pulled out from jitter buffer,
  // update the jitter estimate with what we currently know.
  // This frame shouldn't have been retransmitted, but if we recently
  // turned off NACK this might still happen.
  const bool retransmitted = (oldest_frame->GetNackCount() > 0);
  if (retransmitted) {
    jitter_estimate_.FrameNacked();
  } else if (oldest_frame->Length() > 0) {
    // Ignore retransmitted and empty frames.
    // Update with the previous incomplete frame first
    if (waiting_for_completion_.latest_packet_time >= 0) {
      UpdateJitterEstimate(waiting_for_completion_, true);
    }
    // Then wait for this one to get complete
    waiting_for_completion_.frame_size = oldest_frame->Length();
    waiting_for_completion_.latest_packet_time =
      oldest_frame->LatestPacketTimeMs();
    waiting_for_completion_.timestamp = oldest_frame->TimeStamp();
  }
  frame_list_.erase(frame_list_.begin());

  // Look for previous frame loss
  VerifyAndSetPreviousFrameLost(oldest_frame);

  // The state must be changed to decoding before cleaning up zero sized
  // frames to avoid empty frames being cleaned up and then given to the
  // decoder.
  // Set as decoding. Propagates the missing_frame bit.
  oldest_frame->SetState(kStateDecoding);

  CleanUpOldFrames();

  if (oldest_frame->FrameType() == kVideoFrameKey) {
    waiting_for_key_frame_ = false;
  }

  num_not_decodable_packets_ += oldest_frame->NotDecodablePackets();

  // We have a frame - update decoded state with frame info.
  last_decoded_state_.SetState(oldest_frame);

  return oldest_frame;
}

// Release frame when done with decoding. Should never be used to release
// frames from within the jitter buffer.
void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) {
  CriticalSectionScoped cs(crit_sect_);
  VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame);
  if (frame_buffer)
    frame_buffer->SetState(kStateFree);
}

// Gets frame to use for this timestamp. If no match, get empty frame.
int VCMJitterBuffer::GetFrame(const VCMPacket& packet,
                               VCMEncodedFrame*& frame) {
  if (!running_) {  // Don't accept incoming packets until we are started.
    return VCM_UNINITIALIZED;
  }

  crit_sect_->Enter();
  // Does this packet belong to an old frame?
  if (last_decoded_state_.IsOldPacket(&packet)) {
    // Account only for media packets.
    if (packet.sizeBytes > 0) {
      num_discarded_packets_++;
      num_consecutive_old_packets_++;
    }
    // Update last decoded sequence number if the packet arrived late and
    // belongs to a frame with a timestamp equal to the last decoded
    // timestamp.
    last_decoded_state_.UpdateOldPacket(&packet);

    if (num_consecutive_old_packets_ > kMaxConsecutiveOldPackets) {
      Flush();
      crit_sect_->Leave();
      return VCM_FLUSH_INDICATOR;
    }
    crit_sect_->Leave();
    return VCM_OLD_PACKET_ERROR;
  }
  num_consecutive_old_packets_ = 0;

  FrameList::iterator it = std::find_if(
                             frame_list_.begin(),
                             frame_list_.end(),
                             FrameEqualTimestamp(packet.timestamp));

  if (it != frame_list_.end()) {
    frame = *it;
    crit_sect_->Leave();
    return VCM_OK;
  }

  crit_sect_->Leave();

  // No match, return empty frame.
  frame = GetEmptyFrame();
  if (frame != NULL) {
    return VCM_OK;
  }
  // No free frame! Try to reclaim some...
  crit_sect_->Enter();
  RecycleFramesUntilKeyFrame();
  crit_sect_->Leave();

  frame = GetEmptyFrame();
  if (frame != NULL) {
    return VCM_OK;
  }
  return VCM_JITTER_BUFFER_ERROR;
}

// Deprecated! Kept for testing purposes.
VCMEncodedFrame* VCMJitterBuffer::GetFrame(const VCMPacket& packet) {
  VCMEncodedFrame* frame = NULL;
  if (GetFrame(packet, frame) < 0) {
    return NULL;
  }
  return frame;
}

int64_t VCMJitterBuffer::LastPacketTime(VCMEncodedFrame* frame,
                                        bool* retransmitted) const {
  assert(retransmitted);
  CriticalSectionScoped cs(crit_sect_);
  *retransmitted = (static_cast<VCMFrameBuffer*>(frame)->GetNackCount() > 0);
  return static_cast<VCMFrameBuffer*>(frame)->LatestPacketTimeMs();
}

VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(VCMEncodedFrame* encoded_frame,
                                                 const VCMPacket& packet) {
  assert(encoded_frame);
  CriticalSectionScoped cs(crit_sect_);
  int64_t now_ms = clock_->MillisecondTimestamp();
  VCMFrameBufferEnum buffer_return = kSizeError;
  VCMFrameBufferEnum ret = kSizeError;
  VCMFrameBuffer* frame = static_cast<VCMFrameBuffer*>(encoded_frame);

  // We are keeping track of the first seq num, the latest seq num and
  // the number of wraps to be able to calculate how many packets we expect.
  if (first_packet_) {
    // Now it's time to start estimating jitter
    // reset the delay estimate.
    inter_frame_delay_.Reset(clock_->MillisecondTimestamp());
    first_packet_ = false;
  }

  // Empty packets may bias the jitter estimate (lacking size component),
  // therefore don't let empty packet trigger the following updates:
  if (packet.frameType != kFrameEmpty) {
    if (waiting_for_completion_.timestamp == packet.timestamp) {
      // This can get bad if we have a lot of duplicate packets,
      // we will then count some packet multiple times.
      waiting_for_completion_.frame_size += packet.sizeBytes;
      waiting_for_completion_.latest_packet_time = now_ms;
    } else if (waiting_for_completion_.latest_packet_time >= 0 &&
               waiting_for_completion_.latest_packet_time + 2000 <= now_ms) {
      // A packet should never be more than two seconds late
      UpdateJitterEstimate(waiting_for_completion_, true);
      waiting_for_completion_.latest_packet_time = -1;
      waiting_for_completion_.frame_size = 0;
      waiting_for_completion_.timestamp = 0;
    }
  }

  VCMFrameBufferStateEnum state = frame->GetState();
  last_decoded_state_.UpdateOldPacket(&packet);
  // Insert packet
  // Check for first packet
  // High sequence number will be -1 if neither an empty packet nor
  // a media packet has been inserted.
  bool first = (frame->GetHighSeqNum() == -1);
  // When in Hybrid mode, we allow for a decodable state
  // Note: Under current version, a decodable frame will never be
  // triggered, as the body of the function is empty.
  // TODO(mikhal): Update when decodable is enabled.
  buffer_return = frame->InsertPacket(packet, now_ms,
                                      nack_mode_ == kNackHybrid,
                                      rtt_ms_);
  ret = buffer_return;
  if (buffer_return > 0) {
    incoming_bit_count_ += packet.sizeBytes << 3;

    // Has this packet been nacked or is it about to be nacked?
    if (IsPacketRetransmitted(packet)) {
      frame->IncrementNackCount();
    }

    // Insert each frame once on the arrival of the first packet
    // belonging to that frame (media or empty).
    if (state == kStateEmpty && first) {
      ret = kFirstPacket;
      FrameList::reverse_iterator rit = std::find_if(
          frame_list_.rbegin(),
          frame_list_.rend(),
          FrameSmallerTimestamp(frame->TimeStamp()));
      frame_list_.insert(rit.base(), frame);
    }
  }
  switch (buffer_return) {
    case kStateError:
    case kTimeStampError:
    case kSizeError: {
      if (frame != NULL) {
        // Will be released when it gets old.
        frame->Reset();
        frame->SetState(kStateEmpty);
      }
      break;
    }
    case kCompleteSession: {
      // Only update return value for a JB flush indicator.
      if (UpdateFrameState(frame) == kFlushIndicator)
        ret = kFlushIndicator;
      // Signal that we have a received packet.
      packet_event_.Set();
      break;
    }
    case kDecodableSession:
    case kIncomplete: {
      // Signal that we have a received packet.
      packet_event_.Set();
      break;
    }
    case kNoError:
    case kDuplicatePacket: {
      break;
    }
    default: {
      assert(false && "JitterBuffer::InsertPacket: Undefined value");
    }
  }
  return ret;
}

uint32_t VCMJitterBuffer::EstimatedJitterMs() {
  CriticalSectionScoped cs(crit_sect_);
  uint32_t estimate = VCMJitterEstimator::OPERATING_SYSTEM_JITTER;

  // Compute RTT multiplier for estimation
  // low_rtt_nackThresholdMs_ == -1 means no FEC.
  double rtt_mult = 1.0f;
  if (nack_mode_ == kNackHybrid && (low_rtt_nack_threshold_ms_ >= 0 &&
      static_cast<int>(rtt_ms_) > low_rtt_nack_threshold_ms_)) {
    // from here we count on FEC
    rtt_mult = 0.0f;
  }
  estimate += static_cast<uint32_t>
              (jitter_estimate_.GetJitterEstimate(rtt_mult) + 0.5);
  return estimate;
}

void VCMJitterBuffer::UpdateRtt(uint32_t rtt_ms) {
  CriticalSectionScoped cs(crit_sect_);
  rtt_ms_ = rtt_ms;
  jitter_estimate_.UpdateRtt(rtt_ms);
}

void VCMJitterBuffer::SetNackMode(VCMNackMode mode,
                                  int low_rtt_nack_threshold_ms,
                                  int high_rtt_nack_threshold_ms) {
  CriticalSectionScoped cs(crit_sect_);
  nack_mode_ = mode;
  assert(low_rtt_nack_threshold_ms >= -1 && high_rtt_nack_threshold_ms >= -1);
  assert(high_rtt_nack_threshold_ms == -1 ||
         low_rtt_nack_threshold_ms <= high_rtt_nack_threshold_ms);
  assert(low_rtt_nack_threshold_ms > -1 || high_rtt_nack_threshold_ms == -1);
  low_rtt_nack_threshold_ms_ = low_rtt_nack_threshold_ms;
  high_rtt_nack_threshold_ms_ = high_rtt_nack_threshold_ms;
  if (nack_mode_ == kNoNack) {
    jitter_estimate_.ResetNackCount();
  }
}

VCMNackMode VCMJitterBuffer::nack_mode() const {
  CriticalSectionScoped cs(crit_sect_);
  return nack_mode_;
}

uint16_t* VCMJitterBuffer::CreateNackList(uint16_t* nack_list_size,
                                          bool* list_extended) {
  assert(nack_list_size);
  assert(list_extended);
  // TODO(mikhal/stefan): Refactor to use last_decoded_state.
  CriticalSectionScoped cs(crit_sect_);
  int i = 0;
  int32_t low_seq_num = -1;
  int32_t high_seq_num = -1;
  *list_extended = false;

  // Don't create a NACK list if we won't wait for the retransmitted packets.
  if (!WaitForRetransmissions()) {
    *nack_list_size = 0;
    return NULL;
  }

  // Find the lowest (last decoded) sequence number and
  // the highest (highest sequence number of the newest frame)
  // sequence number. The NACK list is a subset of the range
  // between those two numbers.
  GetLowHighSequenceNumbers(&low_seq_num, &high_seq_num);

  // Build a list of all sequence numbers we have.
  if (low_seq_num == -1 || high_seq_num == -1) {
    // This happens if we lose the first packet, nothing is popped.
    if (high_seq_num == -1) {
      // We have not received any packets yet.
      *nack_list_size = 0;
    } else {
      // Signal that we want a key frame request to be sent.
      *nack_list_size = 0xffff;
    }
    return NULL;
  }

  int number_of_seq_num = 0;
  if (low_seq_num > high_seq_num) {
    if (low_seq_num - high_seq_num > 0x00ff) {
      // Wrap.
      number_of_seq_num = (0xffff - low_seq_num) + high_seq_num + 1;
    }
  } else {
    number_of_seq_num = high_seq_num - low_seq_num;
  }

  if (number_of_seq_num > kNackHistoryLength) {
    // NACK list has grown too big, flush and try to restart.
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Nack list too large, try to find a key frame and restart "
                 "from seq: %d. Lowest seq in jb %d",
                 high_seq_num, low_seq_num);

    // This NACK size will trigger a key frame request.
    bool found_key_frame = false;

    while (number_of_seq_num > kNackHistoryLength) {
      found_key_frame = RecycleFramesUntilKeyFrame();

      if (!found_key_frame) {
        break;
      }

      // Check if we still have too many packets in the jitter buffer.
      low_seq_num = -1;
      high_seq_num = -1;
      GetLowHighSequenceNumbers(&low_seq_num, &high_seq_num);

      if (high_seq_num == -1) {
        assert(low_seq_num != -1);  // This should never happen.
        // We can't calculate the NACK list length.
        return NULL;
      }

      number_of_seq_num = 0;
      if (low_seq_num > high_seq_num) {
        if (low_seq_num - high_seq_num > 0x00ff) {
          // wrap
          number_of_seq_num = (0xffff - low_seq_num) + high_seq_num + 1;
          high_seq_num = low_seq_num;
        }
      } else {
        number_of_seq_num = high_seq_num - low_seq_num;
      }
    }

    if (!found_key_frame) {
      // Set the last decoded sequence number to current high.
      // This is to not get a large nack list again right away.
      last_decoded_state_.SetSeqNum(static_cast<uint16_t>(high_seq_num));
      // Set to trigger key frame signal.
      *nack_list_size = 0xffff;
      *list_extended = true;
      WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, -1,
                   "\tNo key frame found, request one. last_decoded_seq_num_ "
                   "%d", last_decoded_state_.sequence_num());
    } else {
      // We have cleaned up the jitter buffer and found a key frame.
      WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, -1,
                   "\tKey frame found. last_decoded_seq_num_ %d",
                   last_decoded_state_.sequence_num());
      *nack_list_size = 0;
    }

    return NULL;
  }

  uint16_t seq_number_iterator = static_cast<uint16_t>(low_seq_num + 1);
  for (i = 0; i < number_of_seq_num; i++) {
    nack_seq_nums_internal_[i] = seq_number_iterator;
    seq_number_iterator++;
  }
  // Now we have a list of all sequence numbers that could have been sent.
  // Zero out the ones we have received.
  for (i = 0; i < max_number_of_frames_; i++) {
    // We don't need to check if frame is decoding since low_seq_num is based
    // on the last decoded sequence number.
    VCMFrameBufferStateEnum state = frame_buffers_[i]->GetState();
    if ((kStateFree != state) &&
        (kStateEmpty != state)) {
      // Reaching thus far means we are going to update the NACK list
      // When in hybrid mode, we use the soft NACKing feature.
      if (nack_mode_ == kNackHybrid) {
        frame_buffers_[i]->BuildSoftNackList(nack_seq_nums_internal_,
                                             number_of_seq_num,
                                             rtt_ms_);
      } else {
        // Used when the frame is being processed by the decoding thread
        // don't need to use that info in this loop.
        frame_buffers_[i]->BuildHardNackList(nack_seq_nums_internal_,
                                             number_of_seq_num);
      }
    }
  }

  // Compress the list.
  int empty_index = -1;
  for (i = 0; i < number_of_seq_num; i++) {
    if (nack_seq_nums_internal_[i] == -1 || nack_seq_nums_internal_[i] == -2) {
      // This is empty.
      if (empty_index == -1) {
        // No empty index before, remember this position.
        empty_index = i;
      }
    } else {
      // This is not empty.
      if (empty_index == -1) {
        // No empty index, continue.
      } else {
        nack_seq_nums_internal_[empty_index] = nack_seq_nums_internal_[i];
        nack_seq_nums_internal_[i] = -1;
        empty_index++;
      }
    }
  }

  if (empty_index == -1) {
    // No empty.
    *nack_list_size = number_of_seq_num;
  } else {
    *nack_list_size = empty_index;
  }

  if (*nack_list_size > nack_seq_nums_length_) {
    // Larger list: NACK list was extended since the last call.
    *list_extended = true;
  }

  for (unsigned int j = 0; j < *nack_list_size; j++) {
    // Check if the list has been extended since it was last created, i.e,
    // new items have been added.
    if (nack_seq_nums_length_ > j && !*list_extended) {
      unsigned int k = 0;
      for (k = j; k < nack_seq_nums_length_; k++) {
        // Found the item in the last list, i.e, no new items found yet.
        if (nack_seq_nums_[k] ==
            static_cast<uint16_t>(nack_seq_nums_internal_[j])) {
          break;
        }
      }
      if (k == nack_seq_nums_length_) {  // New item not found in last list.
        *list_extended = true;
      }
    } else {
      *list_extended = true;
    }
    nack_seq_nums_[j] = static_cast<uint16_t>(nack_seq_nums_internal_[j]);
  }

  nack_seq_nums_length_ = *nack_list_size;

  return nack_seq_nums_;
}

int64_t VCMJitterBuffer::LastDecodedTimestamp() const {
  CriticalSectionScoped cs(crit_sect_);
  return last_decoded_state_.time_stamp();
}

VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecodingNACK() {
  CleanUpOldFrames();
  // First look for a complete continuous__ frame.
  // When waiting for nack, wait for a key frame, if a continuous frame cannot
  // be determined (i.e. initial decoding state).
  if (last_decoded_state_.init()) {
    waiting_for_key_frame_ = true;
  }
  // Allow for a decodable frame when in Hybrid mode.
  bool enable_decodable = nack_mode_ == kNackHybrid ? true : false;
  FrameList::iterator it = FindOldestCompleteContinuousFrame(enable_decodable);
  if (it == frame_list_.end()) {
    // If we didn't find one we're good with a complete key/decodable frame.
    it = find_if(frame_list_.begin(), frame_list_.end(),
                 CompleteDecodableKeyFrameCriteria());
    if (it == frame_list_.end()) {
      return NULL;
    }
  }
  VCMFrameBuffer* oldest_frame = *it;
  // Update jitter estimate
  const bool retransmitted = (oldest_frame->GetNackCount() > 0);
  if (retransmitted) {
    jitter_estimate_.FrameNacked();
  } else if (oldest_frame->Length() > 0) {
    // Ignore retransmitted and empty frames.
    UpdateJitterEstimate(*oldest_frame, false);
  }
  it = frame_list_.erase(it);

  // Look for previous frame loss.
  VerifyAndSetPreviousFrameLost(oldest_frame);

  // The state must be changed to decoding before cleaning up zero sized
  // frames to avoid empty frames being cleaned up and then given to the
  // decoder.
  oldest_frame->SetState(kStateDecoding);

  // Clean up old frames and empty frames.
  CleanUpOldFrames();

  if (oldest_frame->FrameType() == kVideoFrameKey) {
    waiting_for_key_frame_ = false;
  }

  // We have a frame - update decoded state with frame info.
  last_decoded_state_.SetState(oldest_frame);

  return oldest_frame;
}

// Set the frame state to free and remove it from the sorted
// frame list. Must be called from inside the critical section crit_sect_.
void VCMJitterBuffer::ReleaseFrameIfNotDecoding(VCMFrameBuffer* frame) {
  if (frame != NULL && frame->GetState() != kStateDecoding) {
    frame->SetState(kStateFree);
  }
}

VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() {
  if (!running_) {
    return NULL;
  }

  crit_sect_->Enter();

  for (int i = 0; i < max_number_of_frames_; ++i) {
    if (kStateFree == frame_buffers_[i]->GetState()) {
      // found a free buffer
      frame_buffers_[i]->SetState(kStateEmpty);
      crit_sect_->Leave();
      return frame_buffers_[i];
    }
  }

  // Check if we can increase JB size
  if (max_number_of_frames_ < kMaxNumberOfFrames) {
    VCMFrameBuffer* ptr_new_buffer = new VCMFrameBuffer();
    ptr_new_buffer->SetState(kStateEmpty);
    frame_buffers_[max_number_of_frames_] = ptr_new_buffer;
    max_number_of_frames_++;

    crit_sect_->Leave();
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "JB(0x%x) FB(0x%x): Jitter buffer  increased to:%d frames",
                 this, ptr_new_buffer, max_number_of_frames_);
    return ptr_new_buffer;
  }
  crit_sect_->Leave();

  // We have reached max size, cannot increase JB size
  return NULL;
}

// Recycle oldest frames up to a key frame, used if jitter buffer is completely
// full.
bool VCMJitterBuffer::RecycleFramesUntilKeyFrame() {
  // Remove up to oldest key frame
  while (frame_list_.size() > 0) {
    // Throw at least one frame.
    drop_count_++;
    FrameList::iterator it = frame_list_.begin();
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Jitter buffer drop count:%d, low_seq %d", drop_count_,
                 (*it)->GetLowSeqNum());
    ReleaseFrameIfNotDecoding(*it);
    it = frame_list_.erase(it);
    if (it != frame_list_.end() && (*it)->FrameType() == kVideoFrameKey) {
      // Fake the last_decoded_state to match this key frame.
      last_decoded_state_.SetStateOneBack(*it);
      return true;
    }
  }
  waiting_for_key_frame_ = true;
  last_decoded_state_.Reset();  // TODO(mikhal): No sync.
  return false;
}

// Must be called under the critical section |crit_sect_|.
VCMFrameBufferEnum VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame) {
  if (frame == NULL) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_), "JB(0x%x) FB(0x%x): "
                 "UpdateFrameState NULL frame pointer", this, frame);
    return kNoError;
  }

  int length = frame->Length();
  if (master_) {
    // Only trace the primary jitter buffer to make it possible to parse
    // and plot the trace file.
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "JB(0x%x) FB(0x%x): Complete frame added to jitter buffer,"
                 " size:%d type %d",
                 this, frame, length, frame->FrameType());
  }

  if (length != 0 && !frame->GetCountedFrame()) {
    // Ignore ACK frames.
    incoming_frame_count_++;
    frame->SetCountedFrame(true);
  }

  // Check if we should drop the frame. A complete frame can arrive too late.
  if (last_decoded_state_.IsOldFrame(frame)) {
    // Frame is older than the latest decoded frame, drop it. Will be
    // released by CleanUpOldFrames later.
    frame->Reset();
    frame->SetState(kStateEmpty);
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "JB(0x%x) FB(0x%x): Dropping old frame in Jitter buffer",
                 this, frame);
    drop_count_++;
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Jitter buffer drop count: %d, consecutive drops: %u",
                 drop_count_, num_consecutive_old_frames_);
    // Flush() if this happens consistently.
    num_consecutive_old_frames_++;
    if (num_consecutive_old_frames_ > kMaxConsecutiveOldFrames) {
      Flush();
      return kFlushIndicator;
    }
    return kNoError;
  }
  num_consecutive_old_frames_ = 0;
  frame->SetState(kStateComplete);

  // Update receive statistics. We count all layers, thus when you use layers
  // adding all key and delta frames might differ from frame count.
  if (frame->IsSessionComplete()) {
    switch (frame->FrameType()) {
      case kVideoFrameKey: {
        receive_statistics_[0]++;
        break;
      }
      case kVideoFrameDelta: {
        receive_statistics_[1]++;
        break;
      }
      case kVideoFrameGolden: {
        receive_statistics_[2]++;
        break;
      }
      case kVideoFrameAltRef: {
        receive_statistics_[3]++;
        break;
      }
      default:
        assert(false);
    }
  }
  const FrameList::iterator it = FindOldestCompleteContinuousFrame(false);
  VCMFrameBuffer* old_frame = NULL;
  if (it != frame_list_.end()) {
    old_frame = *it;
  }

  // Only signal if this is the oldest frame.
  // Not necessarily the case due to packet reordering or NACK.
  if (!WaitForRetransmissions() || (old_frame != NULL && old_frame == frame)) {
    frame_event_.Set();
  }
  return kNoError;
}

// Find oldest complete frame used for getting next frame to decode
// Must be called under critical section
FrameList::iterator VCMJitterBuffer::FindOldestCompleteContinuousFrame(
    bool enable_decodable) {
  // If we have more than one frame done since last time, pick oldest.
  VCMFrameBuffer* oldest_frame = NULL;
  FrameList::iterator it = frame_list_.begin();

  // When temporal layers are available, we search for a complete or decodable
  // frame until we hit one of the following:
  // 1. Continuous base or sync layer.
  // 2. The end of the list was reached.
  for (; it != frame_list_.end(); ++it)  {
    oldest_frame = *it;
    VCMFrameBufferStateEnum state = oldest_frame->GetState();
    // Is this frame complete or decodable and continuous?
    if ((state == kStateComplete ||
         (enable_decodable && state == kStateDecodable)) &&
        last_decoded_state_.ContinuousFrame(oldest_frame)) {
      break;
    } else {
      int temporal_id = oldest_frame->TemporalId();
      oldest_frame = NULL;
      if (temporal_id <= 0) {
        // When temporal layers are disabled or we have hit a base layer
        // we break (regardless of continuity and completeness).
        break;
      }
    }
  }

  if (oldest_frame == NULL) {
    // No complete frame no point to continue.
    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.
  return it;
}

// Must be called under the critical section |crit_sect_|.
void VCMJitterBuffer::CleanUpOldFrames() {
  while (frame_list_.size() > 0) {
    VCMFrameBuffer* oldest_frame = frame_list_.front();
    bool next_frame_empty =
        (last_decoded_state_.ContinuousFrame(oldest_frame) &&
         oldest_frame->GetState() == kStateEmpty);
    if (last_decoded_state_.IsOldFrame(oldest_frame) ||
        (next_frame_empty && frame_list_.size() > 1)) {
      ReleaseFrameIfNotDecoding(frame_list_.front());
      frame_list_.erase(frame_list_.begin());
    } else {
      break;
    }
  }
}

void VCMJitterBuffer::VerifyAndSetPreviousFrameLost(VCMFrameBuffer* frame) {
  assert(frame);
  frame->MakeSessionDecodable();  // Make sure the session can be decoded.
  if (frame->FrameType() == kVideoFrameKey)
    return;

  if (!last_decoded_state_.ContinuousFrame(frame))
    frame->SetPreviousFrameLoss();
}

// Must be called from within |crit_sect_|.
bool VCMJitterBuffer::IsPacketRetransmitted(const VCMPacket& packet) const {
  if (nack_seq_nums_length_ > 0) {
    for (unsigned int i = 0; i < nack_seq_nums_length_; i++) {
      if (packet.seqNum == nack_seq_nums_[i]) {
        return true;
      }
    }
  }
  return false;
}

// Must be called under the critical section |crit_sect_|. Should never be
// called with retransmitted frames, they must be filtered out before this
// function is called.
void VCMJitterBuffer::UpdateJitterEstimate(const VCMJitterSample& sample,
                                           bool incomplete_frame) {
  if (sample.latest_packet_time == -1) {
    return;
  }
  if (incomplete_frame) {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_), "Received incomplete frame "
                 "timestamp %u frame size %u at time %u",
                 sample.timestamp, sample.frame_size,
                 MaskWord64ToUWord32(sample.latest_packet_time));
  } else {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_), "Received complete frame "
                 "timestamp %u frame size %u at time %u",
                 sample.timestamp, sample.frame_size,
                 MaskWord64ToUWord32(sample.latest_packet_time));
  }
  UpdateJitterEstimate(sample.latest_packet_time, sample.timestamp,
                       sample.frame_size, incomplete_frame);
}

// Must be called under the critical section crit_sect_. Should never be
// called with retransmitted frames, they must be filtered out before this
// function is called.
void VCMJitterBuffer::UpdateJitterEstimate(const VCMFrameBuffer& frame,
                                           bool incomplete_frame) {
  if (frame.LatestPacketTimeMs() == -1) {
    return;
  }
  // No retransmitted frames should be a part of the jitter
  // estimate.
  if (incomplete_frame) {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Received incomplete frame timestamp %u frame type %d "
                 "frame size %u at time %u, jitter estimate was %u",
                 frame.TimeStamp(), frame.FrameType(), frame.Length(),
                 MaskWord64ToUWord32(frame.LatestPacketTimeMs()),
                 EstimatedJitterMs());
  } else {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_), "Received complete frame "
                 "timestamp %u frame type %d frame size %u at time %u, "
                 "jitter estimate was %u",
                 frame.TimeStamp(), frame.FrameType(), frame.Length(),
                 MaskWord64ToUWord32(frame.LatestPacketTimeMs()),
                 EstimatedJitterMs());
  }
  UpdateJitterEstimate(frame.LatestPacketTimeMs(), frame.TimeStamp(),
                       frame.Length(), incomplete_frame);
}

// Must be called under the critical section |crit_sect_|. Should never be
// called with retransmitted frames, they must be filtered out before this
// function is called.
void VCMJitterBuffer::UpdateJitterEstimate(
    int64_t latest_packet_time_ms,
    uint32_t timestamp,
    unsigned int frame_size,
    bool incomplete_frame) {
  if (latest_packet_time_ms == -1) {
    return;
  }
  int64_t frame_delay;
  // Calculate the delay estimate
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
               VCMId(vcm_id_, receiver_id_),
               "Packet received and sent to jitter estimate with: "
               "timestamp=%u wall_clock=%u", timestamp,
               MaskWord64ToUWord32(latest_packet_time_ms));
  bool not_reordered = inter_frame_delay_.CalculateDelay(timestamp,
                                                      &frame_delay,
                                                      latest_packet_time_ms);
  // Filter out frames which have been reordered in time by the network
  if (not_reordered) {
    // Update the jitter estimate with the new samples
    jitter_estimate_.UpdateEstimate(frame_delay, frame_size, incomplete_frame);
  }
}

// Assumed to be called internally from inside a critical section.
void VCMJitterBuffer::GetLowHighSequenceNumbers(
    int32_t* low_seq_num, int32_t* high_seq_num) const {
  assert(low_seq_num);
  assert(high_seq_num);
  // TODO(mikhal/stefan): Refactor to use last_decoded_state.
  int i = 0;
  int32_t seq_num = -1;

  *high_seq_num = -1;
  *low_seq_num = -1;
  if (!last_decoded_state_.init())
    *low_seq_num = last_decoded_state_.sequence_num();

  // find highest seq numbers
  for (i = 0; i < max_number_of_frames_; ++i) {
    seq_num = frame_buffers_[i]->GetHighSeqNum();

    // Ignore free / empty frames
    VCMFrameBufferStateEnum state = frame_buffers_[i]->GetState();

    if ((kStateFree != state) &&
        (kStateEmpty != state) &&
        (kStateDecoding != state) &&
        seq_num != -1) {
      bool wrap;
      *high_seq_num = LatestSequenceNumber(seq_num, *high_seq_num, &wrap);
    }
  }
}

bool VCMJitterBuffer::WaitForRetransmissions() {
  if (nack_mode_ == kNoNack) {
    // NACK disabled -> don't wait for retransmissions.
    return false;
  } else if (nack_mode_ == kNackInfinite) {
    // NACK only -> always wait for retransmissions.
    return true;
  }
  // Hybrid mode. Evaluate if the RTT is high, and in that case we don't wait
  // for retransmissions.
  if (high_rtt_nack_threshold_ms_ >= 0 &&
      rtt_ms_ >= static_cast<unsigned int>(high_rtt_nack_threshold_ms_)) {
    return false;
  }
  return true;
}
}  // namespace webrtc
