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