summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.h
blob: 795dd4e812126f6557802c3193e41e23d9193455 (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
/*
 *  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 MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
#define MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_

#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/decoder_database.h"
#include "modules/audio_coding/neteq/packet.h"
#include "modules/include/module_common_types_public.h"  // IsNewerTimestamp

namespace webrtc {

class DecoderDatabase;
class StatisticsCalculator;
class TickTimer;

// 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,
               const TickTimer* tick_timer,
               StatisticsCalculator* stats);

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

  PacketBuffer(const PacketBuffer&) = delete;
  PacketBuffer& operator=(const PacketBuffer&) = delete;

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

  // Returns true for an empty buffer.
  virtual bool Empty() const;

  // 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);

  // 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 to the first packet in the buffer. Returns
  // NULL if the buffer is empty.
  virtual const Packet* PeekNextPacket() const;

  // Extracts the first packet in the buffer and returns it.
  // Returns an empty optional if the buffer is empty.
  virtual absl::optional<Packet> GetNextPacket();

  // 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.
  virtual void DiscardOldPackets(uint32_t timestamp_limit,
                                 uint32_t horizon_samples);

  // Discards all packets that are (strictly) older than timestamp_limit.
  virtual void DiscardAllOldPackets(uint32_t timestamp_limit);

  // Removes all packets with a specific payload type from the buffer.
  virtual void DiscardPacketsWithPayloadType(uint8_t payload_type);

  // Returns the number of packets in the buffer, including duplicates and
  // redundant packets.
  virtual size_t NumPacketsInBuffer() const;

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

  // Returns the total duration in samples that the packets in the buffer spans
  // across.
  virtual size_t GetSpanSamples(size_t last_decoded_length,
                                size_t sample_rate,
                                bool count_waiting_time) const;

  // Returns true if the packet buffer contains any DTX or CNG packets.
  virtual bool ContainsDtxOrCngPacket(
      const DecoderDatabase* decoder_database) const;

  // 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:
  void LogPacketDiscarded(int codec_level);

  size_t max_number_of_packets_;
  PacketList buffer_;
  const TickTimer* tick_timer_;
  StatisticsCalculator* stats_;
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_