packet_buffer.cc revision 7df9706a016aba9c10a117b530bcada9ceaa5ab9
1d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org/* 2d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * 4d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * Use of this source code is governed by a BSD-style license 5d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * that can be found in the LICENSE file in the root of the source 6d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * tree. An additional intellectual property rights grant can be found 7d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * in the file PATENTS. All contributing project authors may 8d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org */ 10d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 11d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// This is the implementation of the PacketBuffer class. It is mostly based on 12d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// an STL list. The list is kept sorted at all times so that the next packet to 13d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// decode is at the beginning of the list. 14d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 15d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq4/packet_buffer.h" 16d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 17d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org#include <algorithm> // find_if() 18d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 19d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq4/decoder_database.h" 20d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h" 21d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 22d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgnamespace webrtc { 23d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 24d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Predicate used when inserting packets in the buffer list. 25d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Operator() returns true when |packet| goes before |new_packet|. 26d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgclass NewTimestampIsLarger { 27d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org public: 28d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org explicit NewTimestampIsLarger(const Packet* new_packet) 29d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org : new_packet_(new_packet) { 30d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 31d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org bool operator()(Packet* packet) { 32d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return (*new_packet_ >= *packet); 33d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 34d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 35d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org private: 36d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org const Packet* new_packet_; 37d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}; 38d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 39d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Constructor. The arguments define the maximum number of slots and maximum 40d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// payload memory (excluding RTP headers) that the buffer will accept. 41d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacketBuffer::PacketBuffer(size_t max_number_of_packets, 42d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org size_t max_memory_bytes) 43d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org : max_number_of_packets_(max_number_of_packets), 44d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org max_memory_bytes_(max_memory_bytes), 45d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org current_memory_bytes_(0) { 46d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 47d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 48d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Destructor. All packets in the buffer will be destroyed. 49d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacketBuffer::~PacketBuffer() { 50d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 51d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 52d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 53d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Flush the buffer. All packets in the buffer will be destroyed. 54d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::Flush() { 55d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteAllPackets(&buffer_); 56d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org current_memory_bytes_ = 0; 57d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 58d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 59d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacket(Packet* packet) { 60d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!packet || !packet->payload) { 61d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (packet) { 62d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete packet; 63d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 64d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPacket; 65d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 66d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 67d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int return_val = kOK; 68d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 69d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if ((buffer_.size() >= max_number_of_packets_) || 70d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org (current_memory_bytes_ + packet->payload_length 71d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org > static_cast<int>(max_memory_bytes_))) { 72d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Buffer is full. Flush it. 73d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 74d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return_val = kFlushed; 75d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if ((buffer_.size() >= max_number_of_packets_) || 76d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org (current_memory_bytes_ + packet->payload_length 77d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org > static_cast<int>(max_memory_bytes_))) { 78d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Buffer is still too small for the packet. Either the buffer limits are 79d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // really small, or the packet is really large. Delete the packet and 80d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // return an error. 81d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete [] packet->payload; 82d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete packet; 83d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOversizePacket; 84d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 85d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 86d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 87d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Get an iterator pointing to the place in the buffer where the new packet 88d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // should be inserted. The list is searched from the back, since the most 89d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // likely case is that the new packet should be near the end of the list. 90d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::reverse_iterator rit = std::find_if( 91d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.rbegin(), buffer_.rend(), 92d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org NewTimestampIsLarger(packet)); 93d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.insert(rit.base(), packet); // Insert the packet at that position. 94d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org current_memory_bytes_ += packet->payload_length; 95d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 96d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return return_val; 97d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 98d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 99d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacketList(PacketList* packet_list, 100d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org const DecoderDatabase& decoder_database, 101d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint8_t* current_rtp_payload_type, 102d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint8_t* current_cng_rtp_payload_type) { 103d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org bool flushed = false; 104d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (!packet_list->empty()) { 105d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = packet_list->front(); 106d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (decoder_database.IsComfortNoise(packet->header.payloadType)) { 107d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (*current_cng_rtp_payload_type != 0xFF && 108d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type != packet->header.payloadType) { 109d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // New CNG payload type implies new codec type. 110d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type = 0xFF; 111d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 112d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 113d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 114d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type = packet->header.payloadType; 115d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } else if (!decoder_database.IsDtmf(packet->header.payloadType)) { 116d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // This must be speech. 117d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (*current_rtp_payload_type != 0xFF && 118d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type != packet->header.payloadType) { 119d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type = 0xFF; 120d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 121d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 122d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 123d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type = packet->header.payloadType; 124d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 125d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int return_val = InsertPacket(packet); 126d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org packet_list->pop_front(); 127d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (return_val == kFlushed) { 128d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // The buffer flushed, but this is not an error. We can still continue. 129d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 130d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } else if (return_val != kOK) { 131d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // An error occurred. Delete remaining packets in list and return. 132d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteAllPackets(packet_list); 133d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return return_val; 134d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 135d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 136d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return flushed ? kFlushed : kOK; 137d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 138d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 139d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const { 140d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 141d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 142d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 143d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!next_timestamp) { 144d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPointer; 145d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 146d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *next_timestamp = buffer_.front()->header.timestamp; 147d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 148d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 149d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 150d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextHigherTimestamp(uint32_t timestamp, 151d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint32_t* next_timestamp) const { 152d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 153d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 154d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 155d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!next_timestamp) { 156d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPointer; 157d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 158d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::const_iterator it; 159d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 160d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if ((*it)->header.timestamp >= timestamp) { 161d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Found a packet matching the search. 162d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *next_timestamp = (*it)->header.timestamp; 163d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 164d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 165d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 166d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kNotFound; 167d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 168d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 169d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgconst RTPHeader* PacketBuffer::NextRtpHeader() const { 170d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 171d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return NULL; 172d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 173d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return const_cast<const RTPHeader*>(&(buffer_.front()->header)); 174d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 175d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 176d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacket* PacketBuffer::GetNextPacket(int* discard_count) { 177d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 178d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Buffer is empty. 179d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return NULL; 180d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 181d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 182d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = buffer_.front(); 183d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Assert that the packet sanity checks in InsertPacket method works. 184d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(packet && packet->payload); 185d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.pop_front(); 186d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org current_memory_bytes_ -= packet->payload_length; 187d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(current_memory_bytes_ >= 0); // Assert bookkeeping is correct. 188d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Discard other packets with the same timestamp. These are duplicates or 189d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // redundant payloads that should not be used. 190d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (discard_count) { 191d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *discard_count = 0; 192d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 193d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (!Empty() && 194d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.front()->header.timestamp == packet->header.timestamp) { 195d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (DiscardNextPacket() != kOK) { 196d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(false); // Must be ok by design. 197d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 198d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (discard_count) { 199d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org ++(*discard_count); 200d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 201d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 202d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return packet; 203d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 204d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 205d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::DiscardNextPacket() { 206d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 207d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 208d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 209d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* temp_packet = buffer_.front(); 210d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Assert that the packet sanity checks in InsertPacket method works. 211d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(temp_packet && temp_packet->payload); 212d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org current_memory_bytes_ -= temp_packet->payload_length; 213d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(current_memory_bytes_ >= 0); // Assert bookkeeping is correct. 214d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteFirstPacket(&buffer_); 215d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 216d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 217d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 218d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit) { 219d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int discard_count = 0; 220d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (!Empty() && 221d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org timestamp_limit != buffer_.front()->header.timestamp && 222d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org static_cast<uint32_t>(timestamp_limit 223d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org - buffer_.front()->header.timestamp) < 224d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 0xFFFFFFFF / 2) { 225d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (DiscardNextPacket() != kOK) { 226d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(false); // Must be ok by design. 227d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 228d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org ++discard_count; 229d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 230d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return 0; 231d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 232d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 233d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NumSamplesInBuffer(DecoderDatabase* decoder_database, 234d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int last_decoded_length) const { 235d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::const_iterator it; 236d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int num_samples = 0; 237d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 238d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = (*it); 239d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org AudioDecoder* decoder = 240d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org decoder_database->GetDecoder(packet->header.payloadType); 241d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (decoder) { 242d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int duration = decoder->PacketDuration(packet->payload, 243d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org packet->payload_length); 244d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (duration >= 0) { 245d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org num_samples += duration; 246d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org continue; // Go to next packet in loop. 247d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 248d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 249d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org num_samples += last_decoded_length; 250d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 251d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return num_samples; 252d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 253d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 254d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::IncrementWaitingTimes(int inc) { 255d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::iterator it; 256d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 257d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org (*it)->waiting_time += inc; 258d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 259d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 260d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 261d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgbool PacketBuffer::DeleteFirstPacket(PacketList* packet_list) { 262d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (packet_list->empty()) { 263d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return false; 264d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 265d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* first_packet = packet_list->front(); 266d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete [] first_packet->payload; 267d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete first_packet; 268d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org packet_list->pop_front(); 269d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return true; 270d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 271d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 272d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::DeleteAllPackets(PacketList* packet_list) { 273d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (DeleteFirstPacket(packet_list)) { 274d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Continue while the list is not empty. 275d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 276d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 277d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 2787df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.orgvoid PacketBuffer::BufferStat(int* num_packest, 2797df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org int* max_num_packets, 2807df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org int* current_memory_bytes, 2817df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org int* max_memory_bytes) const { 2827df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org *num_packest = buffer_.size(); 2837df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org *max_num_packets = max_number_of_packets_; 2847df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org *current_memory_bytes = current_memory_bytes_; 2857df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org *max_memory_bytes = max_memory_bytes_; 2867df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org} 2877df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org 288d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} // namespace webrtc 289