packet_buffer.cc revision 116ed1d4f0445fdf215cffa2d9d0946a1cdab3eb
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
39116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.orgPacketBuffer::PacketBuffer(size_t max_number_of_packets)
40116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.org    : max_number_of_packets_(max_number_of_packets) {}
41d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
42d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Destructor. All packets in the buffer will be destroyed.
43d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacketBuffer::~PacketBuffer() {
44d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  Flush();
45d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
46d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
47d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Flush the buffer. All packets in the buffer will be destroyed.
48d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::Flush() {
49d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DeleteAllPackets(&buffer_);
50d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
51d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
52d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacket(Packet* packet) {
53d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (!packet || !packet->payload) {
54d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (packet) {
55d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      delete packet;
56d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
57d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kInvalidPacket;
58d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
59d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
60d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int return_val = kOK;
61d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
62116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.org  if (buffer_.size() >= max_number_of_packets_) {
63d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    // Buffer is full. Flush it.
64d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    Flush();
65d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return_val = kFlushed;
66d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
67d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
68d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Get an iterator pointing to the place in the buffer where the new packet
69d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // should be inserted. The list is searched from the back, since the most
70d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // likely case is that the new packet should be near the end of the list.
71d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  PacketList::reverse_iterator rit = std::find_if(
72d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      buffer_.rbegin(), buffer_.rend(),
73d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      NewTimestampIsLarger(packet));
74d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  buffer_.insert(rit.base(), packet);  // Insert the packet at that position.
75d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
76d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return return_val;
77d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
78d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
79d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::InsertPacketList(PacketList* packet_list,
80d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                                   const DecoderDatabase& decoder_database,
81d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                                   uint8_t* current_rtp_payload_type,
82d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                                   uint8_t* current_cng_rtp_payload_type) {
83d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  bool flushed = false;
84d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (!packet_list->empty()) {
85d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    Packet* packet = packet_list->front();
86d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (decoder_database.IsComfortNoise(packet->header.payloadType)) {
87d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      if (*current_cng_rtp_payload_type != 0xFF &&
88d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org          *current_cng_rtp_payload_type != packet->header.payloadType) {
89d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        // New CNG payload type implies new codec type.
90d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        *current_rtp_payload_type = 0xFF;
91d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        Flush();
92d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        flushed = true;
93d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      }
94d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      *current_cng_rtp_payload_type = packet->header.payloadType;
95d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    } else if (!decoder_database.IsDtmf(packet->header.payloadType)) {
96d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      // This must be speech.
97d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      if (*current_rtp_payload_type != 0xFF &&
98d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org          *current_rtp_payload_type != packet->header.payloadType) {
99d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        *current_cng_rtp_payload_type = 0xFF;
100d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        Flush();
101d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        flushed = true;
102d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      }
103d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      *current_rtp_payload_type = packet->header.payloadType;
104d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
105d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    int return_val = InsertPacket(packet);
106d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    packet_list->pop_front();
107d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (return_val == kFlushed) {
108d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      // The buffer flushed, but this is not an error. We can still continue.
109d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      flushed = true;
110d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    } else if (return_val != kOK) {
111d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      // An error occurred. Delete remaining packets in list and return.
112d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      DeleteAllPackets(packet_list);
113d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      return return_val;
114d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
115d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
116d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return flushed ? kFlushed : kOK;
117d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
118d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
119d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const {
120d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (Empty()) {
121d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kBufferEmpty;
122d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
123d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (!next_timestamp) {
124d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kInvalidPointer;
125d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
126d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  *next_timestamp = buffer_.front()->header.timestamp;
127d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return kOK;
128d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
129d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
130d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NextHigherTimestamp(uint32_t timestamp,
131d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                                      uint32_t* next_timestamp) const {
132d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (Empty()) {
133d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kBufferEmpty;
134d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
135d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (!next_timestamp) {
136d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kInvalidPointer;
137d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
138d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  PacketList::const_iterator it;
139d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
140d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if ((*it)->header.timestamp >= timestamp) {
141d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      // Found a packet matching the search.
142d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      *next_timestamp = (*it)->header.timestamp;
143d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      return kOK;
144d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
145d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
146d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return kNotFound;
147d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
148d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
149d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgconst RTPHeader* PacketBuffer::NextRtpHeader() const {
150d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (Empty()) {
151d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return NULL;
152d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
153d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return const_cast<const RTPHeader*>(&(buffer_.front()->header));
154d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
155d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
156d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgPacket* PacketBuffer::GetNextPacket(int* discard_count) {
157d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (Empty()) {
158d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    // Buffer is empty.
159d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return NULL;
160d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
161d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
162d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  Packet* packet = buffer_.front();
163d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Assert that the packet sanity checks in InsertPacket method works.
164d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  assert(packet && packet->payload);
165d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  buffer_.pop_front();
166d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Discard other packets with the same timestamp. These are duplicates or
167d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // redundant payloads that should not be used.
168d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (discard_count) {
169d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    *discard_count = 0;
170d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
171d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (!Empty() &&
172d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      buffer_.front()->header.timestamp == packet->header.timestamp) {
173d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (DiscardNextPacket() != kOK) {
174d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      assert(false);  // Must be ok by design.
175d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
176d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (discard_count) {
177d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      ++(*discard_count);
178d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
179d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
180d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return packet;
181d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
182d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
183d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::DiscardNextPacket() {
184d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (Empty()) {
185d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return kBufferEmpty;
186d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
187d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  Packet* temp_packet = buffer_.front();
188d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Assert that the packet sanity checks in InsertPacket method works.
189d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  assert(temp_packet && temp_packet->payload);
190d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DeleteFirstPacket(&buffer_);
191d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return kOK;
192d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
193d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
194d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit) {
195d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (!Empty() &&
196d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      timestamp_limit != buffer_.front()->header.timestamp &&
197d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      static_cast<uint32_t>(timestamp_limit
198d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                            - buffer_.front()->header.timestamp) <
199d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                            0xFFFFFFFF / 2) {
200d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (DiscardNextPacket() != kOK) {
201d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      assert(false);  // Must be ok by design.
202d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
203d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
204d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return 0;
205d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
206d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
207d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgint PacketBuffer::NumSamplesInBuffer(DecoderDatabase* decoder_database,
208d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org                                     int last_decoded_length) const {
209d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  PacketList::const_iterator it;
210d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int num_samples = 0;
2117b75ac6756a594d81ae88e8f798b0376886b69f5turaj@webrtc.org  int last_duration = last_decoded_length;
212d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
213d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    Packet* packet = (*it);
214d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    AudioDecoder* decoder =
215d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        decoder_database->GetDecoder(packet->header.payloadType);
216d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    if (decoder) {
217b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org      int duration;
218b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org      if (packet->sync_packet) {
219b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org        duration = last_duration;
220b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org      } else {
221b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org        duration = packet->primary ?
222b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org            decoder->PacketDuration(packet->payload, packet->payload_length) :
223b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org            decoder->PacketDurationRedundant(packet->payload,
224b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org                                             packet->payload_length);
225b28bfa7efcffa3800f64ebd6aeb54face45c180dminyue@webrtc.org      }
226d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      if (duration >= 0) {
2277b75ac6756a594d81ae88e8f798b0376886b69f5turaj@webrtc.org        last_duration = duration;  // Save the most up-to-date (valid) duration.
228d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      }
229d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
2307b75ac6756a594d81ae88e8f798b0376886b69f5turaj@webrtc.org    num_samples += last_duration;
231d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
232d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return num_samples;
233d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
234d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
235d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::IncrementWaitingTimes(int inc) {
236d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  PacketList::iterator it;
237d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
238d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    (*it)->waiting_time += inc;
239d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
240d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
241d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
242d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgbool PacketBuffer::DeleteFirstPacket(PacketList* packet_list) {
243d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  if (packet_list->empty()) {
244d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    return false;
245d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
246d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  Packet* first_packet = packet_list->front();
247d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  delete [] first_packet->payload;
248d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  delete first_packet;
249d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  packet_list->pop_front();
250d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  return true;
251d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
252d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
253d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgvoid PacketBuffer::DeleteAllPackets(PacketList* packet_list) {
254d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (DeleteFirstPacket(packet_list)) {
255d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    // Continue while the list is not empty.
256d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
257d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
258d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
259116ed1d4f0445fdf215cffa2d9d0946a1cdab3ebhenrik.lundin@webrtc.orgvoid PacketBuffer::BufferStat(int* num_packets, int* max_num_packets) const {
260362a55e7b0852a7be95f0d627321503258152551turaj@webrtc.org  *num_packets = static_cast<int>(buffer_.size());
261362a55e7b0852a7be95f0d627321503258152551turaj@webrtc.org  *max_num_packets = static_cast<int>(max_number_of_packets_);
2627df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org}
2637df9706a016aba9c10a117b530bcada9ceaa5ab9turaj@webrtc.org
264d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}  // namespace webrtc
265