13f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org/*
23f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
33f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *
43f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  Use of this source code is governed by a BSD-style license
53f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  that can be found in the LICENSE file in the root of the source
63f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  tree. An additional intellectual property rights grant can be found
73f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  in the file PATENTS.  All contributing project authors may
83f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
93f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org */
103f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
11ed0b4fb2f28fa291e726fc1cf6852611f2176392turaj@webrtc.org#include "webrtc/modules/audio_coding/main/acm2/nack.h"
123f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
133f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org#include <assert.h>  // For assert.
143f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
153f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org#include <algorithm>  // For std::max.
163f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
173f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org#include "webrtc/modules/interface/module_common_types.h"
183f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
193f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
203f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgnamespace webrtc {
213f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
220a1c75a50d10621f70d5921c5b8b9c0eb144bb42turaj@webrtc.orgnamespace acm2 {
230a1c75a50d10621f70d5921c5b8b9c0eb144bb42turaj@webrtc.org
243f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgnamespace {
253f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
263f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgconst int kDefaultSampleRateKhz = 48;
273f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgconst int kDefaultPacketSizeMs = 20;
283f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
293f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}  // namespace
303f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
313f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgNack::Nack(int nack_threshold_packets)
323f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    : nack_threshold_packets_(nack_threshold_packets),
333f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_num_last_received_rtp_(0),
343f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      timestamp_last_received_rtp_(0),
353f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      any_rtp_received_(false),
363f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_num_last_decoded_rtp_(0),
373f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      timestamp_last_decoded_rtp_(0),
383f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      any_rtp_decoded_(false),
393f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sample_rate_khz_(kDefaultSampleRateKhz),
403f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      samples_per_packet_(sample_rate_khz_ * kDefaultPacketSizeMs),
413f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      max_nack_list_size_(kNackListSizeLimit) {}
423f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
433f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgNack* Nack::Create(int nack_threshold_packets) {
443f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return new Nack(nack_threshold_packets);
453f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
463f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
473f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateSampleRate(int sample_rate_hz) {
483f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  assert(sample_rate_hz > 0);
493f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  sample_rate_khz_ = sample_rate_hz / 1000;
503f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
513f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
523f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateLastReceivedPacket(uint16_t sequence_number,
533f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org                                    uint32_t timestamp) {
543f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // Just record the value of sequence number and timestamp if this is the
553f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // first packet.
563f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (!any_rtp_received_) {
573f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    sequence_num_last_received_rtp_ = sequence_number;
583f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    timestamp_last_received_rtp_ = timestamp;
593f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    any_rtp_received_ = true;
603f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // If no packet is decoded, to have a reasonable estimate of time-to-play
613f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // use the given values.
623f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    if (!any_rtp_decoded_) {
633f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_num_last_decoded_rtp_ = sequence_number;
643f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      timestamp_last_decoded_rtp_ = timestamp;
653f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    }
663f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    return;
673f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  }
683f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
693f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (sequence_number == sequence_num_last_received_rtp_)
703f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    return;
713f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
723f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // Received RTP should not be in the list.
733f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  nack_list_.erase(sequence_number);
743f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
753f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // If this is an old sequence number, no more action is required, return.
763f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (IsNewerSequenceNumber(sequence_num_last_received_rtp_, sequence_number))
773f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    return;
783f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
793f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  UpdateSamplesPerPacket(sequence_number, timestamp);
803f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
813f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  UpdateList(sequence_number);
823f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
833f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  sequence_num_last_received_rtp_ = sequence_number;
843f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  timestamp_last_received_rtp_ = timestamp;
853f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  LimitNackListSize();
863f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
873f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
883f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp,
893f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org                                  uint32_t timestamp_current_received_rtp) {
903f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint32_t timestamp_increase = timestamp_current_received_rtp -
913f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      timestamp_last_received_rtp_;
923f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint16_t sequence_num_increase = sequence_number_current_received_rtp -
933f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_num_last_received_rtp_;
943f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
953f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  samples_per_packet_ = timestamp_increase / sequence_num_increase;
963f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
973f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
983f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateList(uint16_t sequence_number_current_received_rtp) {
993f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // Some of the packets which were considered late, now are considered missing.
1003f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  ChangeFromLateToMissing(sequence_number_current_received_rtp);
1013f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1023f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (IsNewerSequenceNumber(sequence_number_current_received_rtp,
1033f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org                            sequence_num_last_received_rtp_ + 1))
1043f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    AddToList(sequence_number_current_received_rtp);
1053f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1063f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1073f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::ChangeFromLateToMissing(
1083f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    uint16_t sequence_number_current_received_rtp) {
1093f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  NackList::const_iterator lower_bound = nack_list_.lower_bound(
1103f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      static_cast<uint16_t>(sequence_number_current_received_rtp -
1113f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org                            nack_threshold_packets_));
1123f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1133f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  for (NackList::iterator it = nack_list_.begin(); it != lower_bound; ++it)
1143f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    it->second.is_missing = true;
1153f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1163f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1173f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orguint32_t Nack::EstimateTimestamp(uint16_t sequence_num) {
1183f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint16_t sequence_num_diff = sequence_num - sequence_num_last_received_rtp_;
1193f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return sequence_num_diff * samples_per_packet_ + timestamp_last_received_rtp_;
1203f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1213f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1223f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::AddToList(uint16_t sequence_number_current_received_rtp) {
1233f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  assert(!any_rtp_decoded_ || IsNewerSequenceNumber(
1243f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_number_current_received_rtp, sequence_num_last_decoded_rtp_));
1253f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1263f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // Packets with sequence numbers older than |upper_bound_missing| are
1273f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  // considered missing, and the rest are considered late.
1283f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint16_t upper_bound_missing = sequence_number_current_received_rtp -
1293f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      nack_threshold_packets_;
1303f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1313f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  for (uint16_t n = sequence_num_last_received_rtp_ + 1;
1323f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      IsNewerSequenceNumber(sequence_number_current_received_rtp, n); ++n) {
1333f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    bool is_missing = IsNewerSequenceNumber(upper_bound_missing, n);
1343f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    uint32_t timestamp = EstimateTimestamp(n);
1353f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    NackElement nack_element(TimeToPlay(timestamp), timestamp, is_missing);
1363f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    nack_list_.insert(nack_list_.end(), std::make_pair(n, nack_element));
1373f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  }
1383f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1393f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1403f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateEstimatedPlayoutTimeBy10ms() {
1413f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  while (!nack_list_.empty() &&
1423f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      nack_list_.begin()->second.time_to_play_ms <= 10)
1433f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    nack_list_.erase(nack_list_.begin());
1443f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1453f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); ++it)
1463f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    it->second.time_to_play_ms -= 10;
1473f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1483f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1493f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::UpdateLastDecodedPacket(uint16_t sequence_number,
1503f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org                                   uint32_t timestamp) {
1513f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (IsNewerSequenceNumber(sequence_number, sequence_num_last_decoded_rtp_) ||
1523f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      !any_rtp_decoded_) {
1533f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    sequence_num_last_decoded_rtp_ = sequence_number;
1543f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    timestamp_last_decoded_rtp_ = timestamp;
1553f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // Packets in the list with sequence numbers less than the
1563f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // sequence number of the decoded RTP should be removed from the lists.
1573f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // They will be discarded by the jitter buffer if they arrive.
1583f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound(
1593f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org        sequence_num_last_decoded_rtp_));
1603f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1613f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // Update estimated time-to-play.
1623f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end();
1633f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org        ++it)
1643f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      it->second.time_to_play_ms = TimeToPlay(it->second.estimated_timestamp);
1653f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  } else {
1663f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    assert(sequence_number == sequence_num_last_decoded_rtp_);
1673f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1683f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // Same sequence number as before. 10 ms is elapsed, update estimations for
1693f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // time-to-play.
1703f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    UpdateEstimatedPlayoutTimeBy10ms();
1713f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1723f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // Update timestamp for better estimate of time-to-play, for packets which
1733f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    // are added to NACK list later on.
1743f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    timestamp_last_decoded_rtp_ += sample_rate_khz_ * 10;
1753f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  }
1763f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  any_rtp_decoded_ = true;
1773f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1783f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1793f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgNack::NackList Nack::GetNackList() const {
1803f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return nack_list_;
1813f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1823f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1833f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::Reset() {
1843f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  nack_list_.clear();
1853f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1863f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  sequence_num_last_received_rtp_ = 0;
1873f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  timestamp_last_received_rtp_ = 0;
1883f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  any_rtp_received_ = false;
1893f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  sequence_num_last_decoded_rtp_ = 0;
1903f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  timestamp_last_decoded_rtp_ = 0;
1913f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  any_rtp_decoded_ = false;
1923f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  sample_rate_khz_ = kDefaultSampleRateKhz;
1933f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  samples_per_packet_ = sample_rate_khz_ * kDefaultPacketSizeMs;
1943f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
1953f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
1963f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgint Nack::SetMaxNackListSize(size_t max_nack_list_size) {
1973f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  if (max_nack_list_size == 0 || max_nack_list_size > kNackListSizeLimit)
1983f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    return -1;
1993f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  max_nack_list_size_ = max_nack_list_size;
2003f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  LimitNackListSize();
2013f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return 0;
2023f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
2033f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
2043f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgvoid Nack::LimitNackListSize() {
2053f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint16_t limit = sequence_num_last_received_rtp_ -
2063f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      static_cast<uint16_t>(max_nack_list_size_) - 1;
2073f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound(limit));
2083f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
2093f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
2103f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgint Nack::TimeToPlay(uint32_t timestamp) const {
2113f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  uint32_t timestamp_increase = timestamp - timestamp_last_decoded_rtp_;
2123f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return timestamp_increase / sample_rate_khz_;
2133f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
2143f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
2153f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org// We don't erase elements with time-to-play shorter than round-trip-time.
2163f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.orgstd::vector<uint16_t> Nack::GetNackList(int round_trip_time_ms) const {
2173f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  std::vector<uint16_t> sequence_numbers;
2183f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  for (NackList::const_iterator it = nack_list_.begin(); it != nack_list_.end();
2193f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      ++it) {
2203f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org    if (it->second.is_missing &&
2213f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org        it->second.time_to_play_ms > round_trip_time_ms)
2223f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org      sequence_numbers.push_back(it->first);
2233f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  }
2243f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org  return sequence_numbers;
2253f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}
2263f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org
2270a1c75a50d10621f70d5921c5b8b9c0eb144bb42turaj@webrtc.org}  // namespace acm2
2280a1c75a50d10621f70d5921c5b8b9c0eb144bb42turaj@webrtc.org
2293f39c00d9875d7e09062725757b789f4da375ef9turaj@webrtc.org}  // namespace webrtc
230