blob: c6fb47ffbfdbfb20fb3e089df61b5e992b610bd5 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
12#define MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000013
Danil Chapovalovb6021232018-06-19 13:26:36 +020014#include "absl/types/optional.h"
Ivo Creusenc7f09ad2018-05-22 13:21:01 +020015#include "modules/audio_coding/neteq/decoder_database.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/audio_coding/neteq/packet.h"
Yves Gerey988cc082018-10-23 12:03:01 +020017#include "modules/include/module_common_types_public.h" // IsNewerTimestamp
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000018
19namespace webrtc {
20
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000021class DecoderDatabase;
minyue-webrtcfae474c2017-07-05 11:17:40 +020022class StatisticsCalculator;
henrik.lundin84f8cd62016-04-26 07:45:16 -070023class TickTimer;
Ivo Creusen7b463c52020-11-25 11:32:40 +010024struct SmartFlushingConfig {
25 // When calculating the flushing threshold, the maximum between the target
26 // level and this value is used.
27 int target_level_threshold_ms = 500;
28 // A smart flush is triggered when the packet buffer contains a multiple of
29 // the target level.
30 int target_level_multiplier = 3;
31};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000032
33// This is the actual buffer holding the packets before decoding.
34class PacketBuffer {
35 public:
36 enum BufferReturnCodes {
37 kOK = 0,
38 kFlushed,
Ivo Creusen7b463c52020-11-25 11:32:40 +010039 kPartialFlush,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000040 kNotFound,
41 kBufferEmpty,
42 kInvalidPacket,
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +000043 kInvalidPointer
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000044 };
45
46 // Constructor creates a buffer which can hold a maximum of
Artem Titovd00ce742021-07-28 20:00:17 +020047 // `max_number_of_packets` packets.
henrik.lundin84f8cd62016-04-26 07:45:16 -070048 PacketBuffer(size_t max_number_of_packets, const TickTimer* tick_timer);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000049
50 // Deletes all packets in the buffer before destroying the buffer.
51 virtual ~PacketBuffer();
52
Byoungchan Lee604fd2f2022-01-21 09:49:39 +090053 PacketBuffer(const PacketBuffer&) = delete;
54 PacketBuffer& operator=(const PacketBuffer&) = delete;
55
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000056 // Flushes the buffer and deletes all packets in it.
Ivo Creusen7b463c52020-11-25 11:32:40 +010057 virtual void Flush(StatisticsCalculator* stats);
58
59 // Partial flush. Flush packets but leave some packets behind.
60 virtual void PartialFlush(int target_level_ms,
61 size_t sample_rate,
62 size_t last_decoded_length,
63 StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000064
65 // Returns true for an empty buffer.
Karl Wiberg7f6c4d42015-04-09 15:44:22 +020066 virtual bool Empty() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000067
Artem Titovd00ce742021-07-28 20:00:17 +020068 // Inserts `packet` into the buffer. The buffer will take over ownership of
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000069 // the packet object.
70 // Returns PacketBuffer::kOK on success, PacketBuffer::kFlushed if the buffer
71 // was flushed due to overfilling.
Ivo Creusen7b463c52020-11-25 11:32:40 +010072 virtual int InsertPacket(Packet&& packet,
73 StatisticsCalculator* stats,
74 size_t last_decoded_length,
75 size_t sample_rate,
76 int target_level_ms,
77 const DecoderDatabase& decoder_database);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000078
79 // Inserts a list of packets into the buffer. The buffer will take over
80 // ownership of the packet objects.
81 // Returns PacketBuffer::kOK if all packets were inserted successfully.
82 // If the buffer was flushed due to overfilling, only a subset of the list is
83 // inserted, and PacketBuffer::kFlushed is returned.
84 // The last three parameters are included for legacy compatibility.
85 // TODO(hlundin): Redesign to not use current_*_payload_type and
86 // decoder_database.
henrik.lundinda8bbf62016-08-31 03:14:11 -070087 virtual int InsertPacketList(
88 PacketList* packet_list,
89 const DecoderDatabase& decoder_database,
Danil Chapovalovb6021232018-06-19 13:26:36 +020090 absl::optional<uint8_t>* current_rtp_payload_type,
91 absl::optional<uint8_t>* current_cng_rtp_payload_type,
Ivo Creusen7b463c52020-11-25 11:32:40 +010092 StatisticsCalculator* stats,
93 size_t last_decoded_length,
94 size_t sample_rate,
95 int target_level_ms);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000096
97 // Gets the timestamp for the first packet in the buffer and writes it to the
Artem Titovd00ce742021-07-28 20:00:17 +020098 // output variable `next_timestamp`.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000099 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
100 // PacketBuffer::kOK otherwise.
101 virtual int NextTimestamp(uint32_t* next_timestamp) const;
102
103 // Gets the timestamp for the first packet in the buffer with a timestamp no
Artem Titovd00ce742021-07-28 20:00:17 +0200104 // lower than the input limit `timestamp`. The result is written to the output
105 // variable `next_timestamp`.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000106 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
107 // PacketBuffer::kOK otherwise.
108 virtual int NextHigherTimestamp(uint32_t timestamp,
109 uint32_t* next_timestamp) const;
110
ossu7a377612016-10-18 04:06:13 -0700111 // Returns a (constant) pointer to the first packet in the buffer. Returns
112 // NULL if the buffer is empty.
113 virtual const Packet* PeekNextPacket() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000114
ossua73f6c92016-10-24 08:25:28 -0700115 // Extracts the first packet in the buffer and returns it.
116 // Returns an empty optional if the buffer is empty.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200117 virtual absl::optional<Packet> GetNextPacket();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000118
119 // Discards the first packet in the buffer. The packet is deleted.
120 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
121 // PacketBuffer::kOK otherwise.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200122 virtual int DiscardNextPacket(StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000123
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000124 // Discards all packets that are (strictly) older than timestamp_limit,
125 // but newer than timestamp_limit - horizon_samples. Setting horizon_samples
126 // to zero implies that the horizon is set to half the timestamp range. That
127 // is, if a packet is more than 2^31 timestamps into the future compared with
128 // timestamp_limit (including wrap-around), it is considered old.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200129 virtual void DiscardOldPackets(uint32_t timestamp_limit,
130 uint32_t horizon_samples,
131 StatisticsCalculator* stats);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000132
133 // Discards all packets that are (strictly) older than timestamp_limit.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200134 virtual void DiscardAllOldPackets(uint32_t timestamp_limit,
135 StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000136
ossu61a208b2016-09-20 01:38:00 -0700137 // Removes all packets with a specific payload type from the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200138 virtual void DiscardPacketsWithPayloadType(uint8_t payload_type,
139 StatisticsCalculator* stats);
ossu61a208b2016-09-20 01:38:00 -0700140
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000141 // Returns the number of packets in the buffer, including duplicates and
142 // redundant packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700143 virtual size_t NumPacketsInBuffer() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000144
145 // Returns the number of samples in the buffer, including samples carried in
146 // duplicate and redundant packets.
ossu61a208b2016-09-20 01:38:00 -0700147 virtual size_t NumSamplesInBuffer(size_t last_decoded_length) const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000148
Jakob Ivarsson1b4254a2019-03-12 15:12:08 +0100149 // Returns the total duration in samples that the packets in the buffer spans
150 // across.
Jakob Ivarsson46dda832019-07-03 16:00:30 +0200151 virtual size_t GetSpanSamples(size_t last_decoded_length,
152 size_t sample_rate,
153 bool count_dtx_waiting_time) const;
Jakob Ivarsson1b4254a2019-03-12 15:12:08 +0100154
Ivo Creusenc7f09ad2018-05-22 13:21:01 +0200155 // Returns true if the packet buffer contains any DTX or CNG packets.
156 virtual bool ContainsDtxOrCngPacket(
157 const DecoderDatabase* decoder_database) const;
158
Artem Titovd00ce742021-07-28 20:00:17 +0200159 // Static method returning true if `timestamp` is older than `timestamp_limit`
160 // but less than `horizon_samples` behind `timestamp_limit`. For instance,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000161 // with timestamp_limit = 100 and horizon_samples = 10, a timestamp in the
162 // range (90, 100) is considered obsolete, and will yield true.
Artem Titovd00ce742021-07-28 20:00:17 +0200163 // Setting `horizon_samples` to 0 is the same as setting it to 2^31, i.e.,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000164 // half the 32-bit timestamp range.
165 static bool IsObsoleteTimestamp(uint32_t timestamp,
166 uint32_t timestamp_limit,
167 uint32_t horizon_samples) {
168 return IsNewerTimestamp(timestamp_limit, timestamp) &&
169 (horizon_samples == 0 ||
170 IsNewerTimestamp(timestamp, timestamp_limit - horizon_samples));
171 }
172
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000173 private:
Ivo Creusen7b463c52020-11-25 11:32:40 +0100174 absl::optional<SmartFlushingConfig> smart_flushing_config_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000175 size_t max_number_of_packets_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000176 PacketList buffer_;
henrik.lundin84f8cd62016-04-26 07:45:16 -0700177 const TickTimer* tick_timer_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000178};
179
180} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200181#endif // MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_