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 159c55f0f957534144d2b8a64154f0a479249b34behenrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/packet_buffer.h" 16d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 17d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org#include <algorithm> // find_if() 18d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 19d67a219bec0c4cde149014984d5dfe168fe0a346Henrik Lundin#include "webrtc/base/logging.h" 20e04a93bcf5e1b608c798a6a3148224b8035f0119kwiberg@webrtc.org#include "webrtc/modules/audio_coding/codecs/audio_decoder.h" 219c55f0f957534144d2b8a64154f0a479249b34behenrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/decoder_database.h" 22d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 23d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgnamespace webrtc { 24d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 25d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Predicate used when inserting packets in the buffer list. 26d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Operator() returns true when |packet| goes before |new_packet|. 27d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgclass NewTimestampIsLarger { 28d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org public: 29d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org explicit NewTimestampIsLarger(const Packet* new_packet) 30d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org : new_packet_(new_packet) { 31d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 32d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org bool operator()(Packet* packet) { 33d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return (*new_packet_ >= *packet); 34d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 35d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 36d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org private: 37d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org const Packet* new_packet_; 38d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}; 39d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 40116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.orgPacketBuffer::PacketBuffer(size_t max_number_of_packets) 41116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.org : max_number_of_packets_(max_number_of_packets) {} 42d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 43d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Destructor. All packets in the buffer will be destroyed. 44d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacketBuffer::~PacketBuffer() { 45d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 46d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 47d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 48d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Flush the buffer. All packets in the buffer will be destroyed. 49d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::Flush() { 50d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteAllPackets(&buffer_); 51d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 52d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 537f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wibergbool PacketBuffer::Empty() const { 547f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg return buffer_.empty(); 557f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg} 567f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg 57d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacket(Packet* packet) { 58d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!packet || !packet->payload) { 59d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (packet) { 60d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete packet; 61d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 62d67a219bec0c4cde149014984d5dfe168fe0a346Henrik Lundin LOG(LS_WARNING) << "InsertPacket invalid packet"; 63d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPacket; 64d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 65d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 66d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int return_val = kOK; 67d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 68116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.org if (buffer_.size() >= max_number_of_packets_) { 69d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Buffer is full. Flush it. 70d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 71d67a219bec0c4cde149014984d5dfe168fe0a346Henrik Lundin LOG(LS_WARNING) << "Packet buffer flushed"; 72d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return_val = kFlushed; 73d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 74d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 75d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Get an iterator pointing to the place in the buffer where the new packet 76d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // should be inserted. The list is searched from the back, since the most 77d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // likely case is that the new packet should be near the end of the list. 78d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::reverse_iterator rit = std::find_if( 79d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.rbegin(), buffer_.rend(), 80d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org NewTimestampIsLarger(packet)); 81c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org 82c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // The new packet is to be inserted to the right of |rit|. If it has the same 83c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // timestamp as |rit|, which has a higher priority, do not insert the new 84c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // packet to list. 85c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org if (rit != buffer_.rend() && 86c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org packet->header.timestamp == (*rit)->header.timestamp) { 87c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org delete [] packet->payload; 88c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org delete packet; 89c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org return return_val; 90c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org } 91c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org 92c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // The new packet is to be inserted to the left of |it|. If it has the same 93c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // timestamp as |it|, which has a lower priority, replace |it| with the new 94c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // packet. 95c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org PacketList::iterator it = rit.base(); 96c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org if (it != buffer_.end() && 97c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org packet->header.timestamp == (*it)->header.timestamp) { 98c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org delete [] (*it)->payload; 99c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org delete *it; 100c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org it = buffer_.erase(it); 101c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org } 102c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org buffer_.insert(it, packet); // Insert the packet at that position. 103d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 104d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return return_val; 105d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 106d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 107d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacketList(PacketList* packet_list, 108d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org const DecoderDatabase& decoder_database, 109d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint8_t* current_rtp_payload_type, 110d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint8_t* current_cng_rtp_payload_type) { 111d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org bool flushed = false; 112d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (!packet_list->empty()) { 113d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = packet_list->front(); 114d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (decoder_database.IsComfortNoise(packet->header.payloadType)) { 115d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (*current_cng_rtp_payload_type != 0xFF && 116d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type != packet->header.payloadType) { 117d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // New CNG payload type implies new codec type. 118d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type = 0xFF; 119d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 120d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 121d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 122d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type = packet->header.payloadType; 123d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } else if (!decoder_database.IsDtmf(packet->header.payloadType)) { 124d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // This must be speech. 125d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (*current_rtp_payload_type != 0xFF && 126d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type != packet->header.payloadType) { 127d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_cng_rtp_payload_type = 0xFF; 128d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Flush(); 129d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 130d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 131d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *current_rtp_payload_type = packet->header.payloadType; 132d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 133d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org int return_val = InsertPacket(packet); 134d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org packet_list->pop_front(); 135d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (return_val == kFlushed) { 136d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // The buffer flushed, but this is not an error. We can still continue. 137d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org flushed = true; 138d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } else if (return_val != kOK) { 139d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // An error occurred. Delete remaining packets in list and return. 140d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteAllPackets(packet_list); 141d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return return_val; 142d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 143d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 144d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return flushed ? kFlushed : kOK; 145d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 146d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 147d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const { 148d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 149d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 150d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 151d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!next_timestamp) { 152d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPointer; 153d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 154d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *next_timestamp = buffer_.front()->header.timestamp; 155d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 156d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 157d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 158d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextHigherTimestamp(uint32_t timestamp, 159d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org uint32_t* next_timestamp) const { 160d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 161d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 162d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 163d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (!next_timestamp) { 164d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kInvalidPointer; 165d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 166d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::const_iterator it; 167d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 168d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if ((*it)->header.timestamp >= timestamp) { 169d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Found a packet matching the search. 170d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org *next_timestamp = (*it)->header.timestamp; 171d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 172d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 173d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 174d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kNotFound; 175d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 176d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 177d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgconst RTPHeader* PacketBuffer::NextRtpHeader() const { 178d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 179d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return NULL; 180d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 181d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return const_cast<const RTPHeader*>(&(buffer_.front()->header)); 182d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 183d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 184dce40cf804019a9898b6ab8d8262466b697c56e0Peter KastingPacket* PacketBuffer::GetNextPacket(size_t* discard_count) { 185d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 186d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Buffer is empty. 187d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return NULL; 188d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 189d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 190d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = buffer_.front(); 191d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Assert that the packet sanity checks in InsertPacket method works. 192d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(packet && packet->payload); 193d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.pop_front(); 194c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org 195d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Discard other packets with the same timestamp. These are duplicates or 196d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // redundant payloads that should not be used. 197dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t discards = 0; 198c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org 199d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (!Empty() && 200d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org buffer_.front()->header.timestamp == packet->header.timestamp) { 201d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (DiscardNextPacket() != kOK) { 202d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(false); // Must be ok by design. 203d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 204c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org ++discards; 205d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 206c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // The way of inserting packet should not cause any packet discarding here. 207c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org // TODO(minyue): remove |discard_count|. 208c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org assert(discards == 0); 209c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org if (discard_count) 210c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org *discard_count = discards; 211c803907d874971faabe790af1604c8ca6d8a1daeminyue@webrtc.org 212d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return packet; 213d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 214d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 215d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::DiscardNextPacket() { 216d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (Empty()) { 217d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kBufferEmpty; 218d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 219d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Assert that the packet sanity checks in InsertPacket method works. 22012a34247a448fa76ba7e13cef3e8b3561d168909henrik.lundin@webrtc.org assert(buffer_.front()); 22112a34247a448fa76ba7e13cef3e8b3561d168909henrik.lundin@webrtc.org assert(buffer_.front()->payload); 222d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org DeleteFirstPacket(&buffer_); 223d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return kOK; 224d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 225d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 22652b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.orgint PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit, 22752b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.org uint32_t horizon_samples) { 22852b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.org while (!Empty() && timestamp_limit != buffer_.front()->header.timestamp && 22952b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.org IsObsoleteTimestamp(buffer_.front()->header.timestamp, 23052b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.org timestamp_limit, 23152b42cb069a035f10e951195c28cf6d05d1fd91chenrik.lundin@webrtc.org horizon_samples)) { 232d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (DiscardNextPacket() != kOK) { 233d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org assert(false); // Must be ok by design. 234d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 235d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 236d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return 0; 237d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 238d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 2397f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wibergint PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit) { 2407f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg return DiscardOldPackets(timestamp_limit, 0); 2417f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg} 2427f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg 243dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingsize_t PacketBuffer::NumPacketsInBuffer() const { 244dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting return buffer_.size(); 2457f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg} 2467f6c4d42a2605d1da39af3f957a46cf57b043b84Karl Wiberg 247dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingsize_t PacketBuffer::NumSamplesInBuffer(DecoderDatabase* decoder_database, 248dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t last_decoded_length) const { 249d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::const_iterator it; 250dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t num_samples = 0; 251dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t last_duration = last_decoded_length; 252d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 253d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* packet = (*it); 254d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org AudioDecoder* decoder = 255d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org decoder_database->GetDecoder(packet->header.payloadType); 256728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting if (decoder && !packet->sync_packet) { 257728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting if (!packet->primary) { 2580aa3ee661c11eda7babdd92fd8a3f25c8d7a1fd0minyue@webrtc.org continue; 259b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org } 260728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting int duration = 261b297c5a01f88219da26cffe433804963d1b70f0fpkasting decoder->PacketDuration(packet->payload, packet->payload_length); 262d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (duration >= 0) { 2637b75ac6756a594d81ae88e8f798b0376886b69f5turaj@webrtc.org last_duration = duration; // Save the most up-to-date (valid) duration. 264d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 265d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 2667b75ac6756a594d81ae88e8f798b0376886b69f5turaj@webrtc.org num_samples += last_duration; 267d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 268d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return num_samples; 269d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 270d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 271d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::IncrementWaitingTimes(int inc) { 272d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org PacketList::iterator it; 273d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org for (it = buffer_.begin(); it != buffer_.end(); ++it) { 274d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org (*it)->waiting_time += inc; 275d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 276d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 277d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 278d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgbool PacketBuffer::DeleteFirstPacket(PacketList* packet_list) { 279d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org if (packet_list->empty()) { 280d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return false; 281d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 282d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org Packet* first_packet = packet_list->front(); 283d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete [] first_packet->payload; 284d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org delete first_packet; 285d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org packet_list->pop_front(); 286d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org return true; 287d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 288d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 289d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::DeleteAllPackets(PacketList* packet_list) { 290d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org while (DeleteFirstPacket(packet_list)) { 291d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org // Continue while the list is not empty. 292d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org } 293d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} 294d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org 295116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.orgvoid PacketBuffer::BufferStat(int* num_packets, int* max_num_packets) const { 296362a55e7b0852a7be95f0d627321503258152551turaj@webrtc.org *num_packets = static_cast<int>(buffer_.size()); 297362a55e7b0852a7be95f0d627321503258152551turaj@webrtc.org *max_num_packets = static_cast<int>(max_number_of_packets_); 2987df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org} 2997df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org 300d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org} // namespace webrtc 301