blob: 20a053323ab52cfb19a93f588df938f482015ada [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
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/constructor_magic.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000019
20namespace webrtc {
21
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000022class DecoderDatabase;
minyue-webrtcfae474c2017-07-05 11:17:40 +020023class StatisticsCalculator;
henrik.lundin84f8cd62016-04-26 07:45:16 -070024class TickTimer;
Ivo Creusen7b463c52020-11-25 11:32:40 +010025struct SmartFlushingConfig {
26 // When calculating the flushing threshold, the maximum between the target
27 // level and this value is used.
28 int target_level_threshold_ms = 500;
29 // A smart flush is triggered when the packet buffer contains a multiple of
30 // the target level.
31 int target_level_multiplier = 3;
32};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000033
34// This is the actual buffer holding the packets before decoding.
35class PacketBuffer {
36 public:
37 enum BufferReturnCodes {
38 kOK = 0,
39 kFlushed,
Ivo Creusen7b463c52020-11-25 11:32:40 +010040 kPartialFlush,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000041 kNotFound,
42 kBufferEmpty,
43 kInvalidPacket,
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +000044 kInvalidPointer
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000045 };
46
47 // Constructor creates a buffer which can hold a maximum of
Artem Titovd00ce742021-07-28 20:00:17 +020048 // `max_number_of_packets` packets.
henrik.lundin84f8cd62016-04-26 07:45:16 -070049 PacketBuffer(size_t max_number_of_packets, const TickTimer* tick_timer);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000050
51 // Deletes all packets in the buffer before destroying the buffer.
52 virtual ~PacketBuffer();
53
54 // Flushes the buffer and deletes all packets in it.
Ivo Creusen7b463c52020-11-25 11:32:40 +010055 virtual void Flush(StatisticsCalculator* stats);
56
57 // Partial flush. Flush packets but leave some packets behind.
58 virtual void PartialFlush(int target_level_ms,
59 size_t sample_rate,
60 size_t last_decoded_length,
61 StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000062
63 // Returns true for an empty buffer.
Karl Wiberg7f6c4d42015-04-09 15:44:22 +020064 virtual bool Empty() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000065
Artem Titovd00ce742021-07-28 20:00:17 +020066 // Inserts `packet` into the buffer. The buffer will take over ownership of
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000067 // the packet object.
68 // Returns PacketBuffer::kOK on success, PacketBuffer::kFlushed if the buffer
69 // was flushed due to overfilling.
Ivo Creusen7b463c52020-11-25 11:32:40 +010070 virtual int InsertPacket(Packet&& packet,
71 StatisticsCalculator* stats,
72 size_t last_decoded_length,
73 size_t sample_rate,
74 int target_level_ms,
75 const DecoderDatabase& decoder_database);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000076
77 // Inserts a list of packets into the buffer. The buffer will take over
78 // ownership of the packet objects.
79 // Returns PacketBuffer::kOK if all packets were inserted successfully.
80 // If the buffer was flushed due to overfilling, only a subset of the list is
81 // inserted, and PacketBuffer::kFlushed is returned.
82 // The last three parameters are included for legacy compatibility.
83 // TODO(hlundin): Redesign to not use current_*_payload_type and
84 // decoder_database.
henrik.lundinda8bbf62016-08-31 03:14:11 -070085 virtual int InsertPacketList(
86 PacketList* packet_list,
87 const DecoderDatabase& decoder_database,
Danil Chapovalovb6021232018-06-19 13:26:36 +020088 absl::optional<uint8_t>* current_rtp_payload_type,
89 absl::optional<uint8_t>* current_cng_rtp_payload_type,
Ivo Creusen7b463c52020-11-25 11:32:40 +010090 StatisticsCalculator* stats,
91 size_t last_decoded_length,
92 size_t sample_rate,
93 int target_level_ms);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000094
95 // Gets the timestamp for the first packet in the buffer and writes it to the
Artem Titovd00ce742021-07-28 20:00:17 +020096 // output variable `next_timestamp`.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000097 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
98 // PacketBuffer::kOK otherwise.
99 virtual int NextTimestamp(uint32_t* next_timestamp) const;
100
101 // Gets the timestamp for the first packet in the buffer with a timestamp no
Artem Titovd00ce742021-07-28 20:00:17 +0200102 // lower than the input limit `timestamp`. The result is written to the output
103 // variable `next_timestamp`.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000104 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
105 // PacketBuffer::kOK otherwise.
106 virtual int NextHigherTimestamp(uint32_t timestamp,
107 uint32_t* next_timestamp) const;
108
ossu7a377612016-10-18 04:06:13 -0700109 // Returns a (constant) pointer to the first packet in the buffer. Returns
110 // NULL if the buffer is empty.
111 virtual const Packet* PeekNextPacket() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000112
ossua73f6c92016-10-24 08:25:28 -0700113 // Extracts the first packet in the buffer and returns it.
114 // Returns an empty optional if the buffer is empty.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200115 virtual absl::optional<Packet> GetNextPacket();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000116
117 // Discards the first packet in the buffer. The packet is deleted.
118 // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
119 // PacketBuffer::kOK otherwise.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200120 virtual int DiscardNextPacket(StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000121
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000122 // Discards all packets that are (strictly) older than timestamp_limit,
123 // but newer than timestamp_limit - horizon_samples. Setting horizon_samples
124 // to zero implies that the horizon is set to half the timestamp range. That
125 // is, if a packet is more than 2^31 timestamps into the future compared with
126 // timestamp_limit (including wrap-around), it is considered old.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200127 virtual void DiscardOldPackets(uint32_t timestamp_limit,
128 uint32_t horizon_samples,
129 StatisticsCalculator* stats);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000130
131 // Discards all packets that are (strictly) older than timestamp_limit.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200132 virtual void DiscardAllOldPackets(uint32_t timestamp_limit,
133 StatisticsCalculator* stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000134
ossu61a208b2016-09-20 01:38:00 -0700135 // Removes all packets with a specific payload type from the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200136 virtual void DiscardPacketsWithPayloadType(uint8_t payload_type,
137 StatisticsCalculator* stats);
ossu61a208b2016-09-20 01:38:00 -0700138
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000139 // Returns the number of packets in the buffer, including duplicates and
140 // redundant packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700141 virtual size_t NumPacketsInBuffer() const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000142
143 // Returns the number of samples in the buffer, including samples carried in
144 // duplicate and redundant packets.
ossu61a208b2016-09-20 01:38:00 -0700145 virtual size_t NumSamplesInBuffer(size_t last_decoded_length) const;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000146
Jakob Ivarsson1b4254a2019-03-12 15:12:08 +0100147 // Returns the total duration in samples that the packets in the buffer spans
148 // across.
Jakob Ivarsson46dda832019-07-03 16:00:30 +0200149 virtual size_t GetSpanSamples(size_t last_decoded_length,
150 size_t sample_rate,
151 bool count_dtx_waiting_time) const;
Jakob Ivarsson1b4254a2019-03-12 15:12:08 +0100152
Ivo Creusenc7f09ad2018-05-22 13:21:01 +0200153 // Returns true if the packet buffer contains any DTX or CNG packets.
154 virtual bool ContainsDtxOrCngPacket(
155 const DecoderDatabase* decoder_database) const;
156
Artem Titovd00ce742021-07-28 20:00:17 +0200157 // Static method returning true if `timestamp` is older than `timestamp_limit`
158 // but less than `horizon_samples` behind `timestamp_limit`. For instance,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000159 // with timestamp_limit = 100 and horizon_samples = 10, a timestamp in the
160 // range (90, 100) is considered obsolete, and will yield true.
Artem Titovd00ce742021-07-28 20:00:17 +0200161 // 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 +0000162 // half the 32-bit timestamp range.
163 static bool IsObsoleteTimestamp(uint32_t timestamp,
164 uint32_t timestamp_limit,
165 uint32_t horizon_samples) {
166 return IsNewerTimestamp(timestamp_limit, timestamp) &&
167 (horizon_samples == 0 ||
168 IsNewerTimestamp(timestamp, timestamp_limit - horizon_samples));
169 }
170
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000171 private:
Ivo Creusen7b463c52020-11-25 11:32:40 +0100172 absl::optional<SmartFlushingConfig> smart_flushing_config_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000173 size_t max_number_of_packets_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000174 PacketList buffer_;
henrik.lundin84f8cd62016-04-26 07:45:16 -0700175 const TickTimer* tick_timer_;
henrikg3c089d72015-09-16 05:37:44 -0700176 RTC_DISALLOW_COPY_AND_ASSIGN(PacketBuffer);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000177};
178
179} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200180#endif // MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_