summaryrefslogtreecommitdiff
path: root/modules/audio_coding/neteq/packet_buffer.h
blob: b9a16189449d0a6cad295d2bd6a1779da8661996 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_

#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/audio_coding/neteq/packet.h"
#include "webrtc/typedefs.h"

namespace webrtc {

// Forward declaration.
class DecoderDatabase;

// This is the actual buffer holding the packets before decoding.
class PacketBuffer {
 public:
  enum BufferReturnCodes {
    kOK = 0,
    kFlushed,
    kNotFound,
    kBufferEmpty,
    kInvalidPacket,
    kInvalidPointer
  };

  // Constructor creates a buffer which can hold a maximum of
  // |max_number_of_packets| packets.
  PacketBuffer(size_t max_number_of_packets);

  // Deletes all packets in the buffer before destroying the buffer.
  virtual ~PacketBuffer();

  // Flushes the buffer and deletes all packets in it.
  virtual void Flush();

  // Returns true for an empty buffer.
  virtual bool Empty() const { return buffer_.empty(); }

  // Inserts |packet| into the buffer. The buffer will take over ownership of
  // the packet object.
  // Returns PacketBuffer::kOK on success, PacketBuffer::kFlushed if the buffer
  // was flushed due to overfilling.
  virtual int InsertPacket(Packet* packet);

  // Inserts a list of packets into the buffer. The buffer will take over
  // ownership of the packet objects.
  // Returns PacketBuffer::kOK if all packets were inserted successfully.
  // If the buffer was flushed due to overfilling, only a subset of the list is
  // inserted, and PacketBuffer::kFlushed is returned.
  // The last three parameters are included for legacy compatibility.
  // TODO(hlundin): Redesign to not use current_*_payload_type and
  // decoder_database.
  virtual int InsertPacketList(PacketList* packet_list,
                               const DecoderDatabase& decoder_database,
                               uint8_t* current_rtp_payload_type,
                               uint8_t* current_cng_rtp_payload_type);

  // Gets the timestamp for the first packet in the buffer and writes it to the
  // output variable |next_timestamp|.
  // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
  // PacketBuffer::kOK otherwise.
  virtual int NextTimestamp(uint32_t* next_timestamp) const;

  // Gets the timestamp for the first packet in the buffer with a timestamp no
  // lower than the input limit |timestamp|. The result is written to the output
  // variable |next_timestamp|.
  // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
  // PacketBuffer::kOK otherwise.
  virtual int NextHigherTimestamp(uint32_t timestamp,
                                  uint32_t* next_timestamp) const;

  // Returns a (constant) pointer the RTP header of the first packet in the
  // buffer. Returns NULL if the buffer is empty.
  virtual const RTPHeader* NextRtpHeader() const;

  // Extracts the first packet in the buffer and returns a pointer to it.
  // Returns NULL if the buffer is empty. The caller is responsible for deleting
  // the packet.
  // Subsequent packets with the same timestamp as the one extracted will be
  // discarded and properly deleted. The number of discarded packets will be
  // written to the output variable |discard_count|.
  virtual Packet* GetNextPacket(int* discard_count);

  // Discards the first packet in the buffer. The packet is deleted.
  // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
  // PacketBuffer::kOK otherwise.
  virtual int DiscardNextPacket();

  // Discards all packets that are (strictly) older than timestamp_limit,
  // but newer than timestamp_limit - horizon_samples. Setting horizon_samples
  // to zero implies that the horizon is set to half the timestamp range. That
  // is, if a packet is more than 2^31 timestamps into the future compared with
  // timestamp_limit (including wrap-around), it is considered old.
  // Returns number of packets discarded.
  virtual int DiscardOldPackets(uint32_t timestamp_limit,
                                uint32_t horizon_samples);

  // Discards all packets that are (strictly) older than timestamp_limit.
  virtual int DiscardAllOldPackets(uint32_t timestamp_limit) {
    return DiscardOldPackets(timestamp_limit, 0);
  }

  // Returns the number of packets in the buffer, including duplicates and
  // redundant packets.
  virtual int NumPacketsInBuffer() const {
    return static_cast<int>(buffer_.size());
  }

  // Returns the number of samples in the buffer, including samples carried in
  // duplicate and redundant packets.
  virtual int NumSamplesInBuffer(DecoderDatabase* decoder_database,
                                 int last_decoded_length) const;

  // Increase the waiting time counter for every packet in the buffer by |inc|.
  // The default value for |inc| is 1.
  virtual void IncrementWaitingTimes(int inc = 1);

  virtual void BufferStat(int* num_packets, int* max_num_packets) const;

  // Static method that properly deletes the first packet, and its payload
  // array, in |packet_list|. Returns false if |packet_list| already was empty,
  // otherwise true.
  static bool DeleteFirstPacket(PacketList* packet_list);

  // Static method that properly deletes all packets, and their payload arrays,
  // in |packet_list|.
  static void DeleteAllPackets(PacketList* packet_list);

  // Static method returning true if |timestamp| is older than |timestamp_limit|
  // but less than |horizon_samples| behind |timestamp_limit|. For instance,
  // with timestamp_limit = 100 and horizon_samples = 10, a timestamp in the
  // range (90, 100) is considered obsolete, and will yield true.
  // Setting |horizon_samples| to 0 is the same as setting it to 2^31, i.e.,
  // half the 32-bit timestamp range.
  static bool IsObsoleteTimestamp(uint32_t timestamp,
                                  uint32_t timestamp_limit,
                                  uint32_t horizon_samples) {
    return IsNewerTimestamp(timestamp_limit, timestamp) &&
           (horizon_samples == 0 ||
            IsNewerTimestamp(timestamp, timestamp_limit - horizon_samples));
  }

 private:
  size_t max_number_of_packets_;
  PacketList buffer_;
  DISALLOW_COPY_AND_ASSIGN(PacketBuffer);
};

}  // namespace webrtc
#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_