1 /* 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 11 #ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_ 12 #define MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_ 13 14 #include "absl/types/optional.h" 15 #include "modules/audio_coding/neteq/decoder_database.h" 16 #include "modules/audio_coding/neteq/packet.h" 17 #include "modules/include/module_common_types_public.h" // IsNewerTimestamp 18 19 namespace webrtc { 20 21 class DecoderDatabase; 22 class StatisticsCalculator; 23 class TickTimer; 24 struct 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 }; 32 33 // This is the actual buffer holding the packets before decoding. 34 class PacketBuffer { 35 public: 36 enum BufferReturnCodes { 37 kOK = 0, 38 kFlushed, 39 kPartialFlush, 40 kNotFound, 41 kBufferEmpty, 42 kInvalidPacket, 43 kInvalidPointer 44 }; 45 46 // Constructor creates a buffer which can hold a maximum of 47 // `max_number_of_packets` packets. 48 PacketBuffer(size_t max_number_of_packets, const TickTimer* tick_timer); 49 50 // Deletes all packets in the buffer before destroying the buffer. 51 virtual ~PacketBuffer(); 52 53 PacketBuffer(const PacketBuffer&) = delete; 54 PacketBuffer& operator=(const PacketBuffer&) = delete; 55 56 // Flushes the buffer and deletes all packets in it. 57 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); 64 65 // Returns true for an empty buffer. 66 virtual bool Empty() const; 67 68 // Inserts `packet` into the buffer. The buffer will take over ownership of 69 // the packet object. 70 // Returns PacketBuffer::kOK on success, PacketBuffer::kFlushed if the buffer 71 // was flushed due to overfilling. 72 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); 78 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. 87 virtual int InsertPacketList( 88 PacketList* packet_list, 89 const DecoderDatabase& decoder_database, 90 absl::optional<uint8_t>* current_rtp_payload_type, 91 absl::optional<uint8_t>* current_cng_rtp_payload_type, 92 StatisticsCalculator* stats, 93 size_t last_decoded_length, 94 size_t sample_rate, 95 int target_level_ms); 96 97 // Gets the timestamp for the first packet in the buffer and writes it to the 98 // output variable `next_timestamp`. 99 // 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 104 // lower than the input limit `timestamp`. The result is written to the output 105 // variable `next_timestamp`. 106 // 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 111 // 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; 114 115 // Extracts the first packet in the buffer and returns it. 116 // Returns an empty optional if the buffer is empty. 117 virtual absl::optional<Packet> GetNextPacket(); 118 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. 122 virtual int DiscardNextPacket(StatisticsCalculator* stats); 123 124 // 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. 129 virtual void DiscardOldPackets(uint32_t timestamp_limit, 130 uint32_t horizon_samples, 131 StatisticsCalculator* stats); 132 133 // Discards all packets that are (strictly) older than timestamp_limit. 134 virtual void DiscardAllOldPackets(uint32_t timestamp_limit, 135 StatisticsCalculator* stats); 136 137 // Removes all packets with a specific payload type from the buffer. 138 virtual void DiscardPacketsWithPayloadType(uint8_t payload_type, 139 StatisticsCalculator* stats); 140 141 // Returns the number of packets in the buffer, including duplicates and 142 // redundant packets. 143 virtual size_t NumPacketsInBuffer() const; 144 145 // Returns the number of samples in the buffer, including samples carried in 146 // duplicate and redundant packets. 147 virtual size_t NumSamplesInBuffer(size_t last_decoded_length) const; 148 149 // Returns the total duration in samples that the packets in the buffer spans 150 // across. 151 virtual size_t GetSpanSamples(size_t last_decoded_length, 152 size_t sample_rate, 153 bool count_dtx_waiting_time) const; 154 155 // Returns true if the packet buffer contains any DTX or CNG packets. 156 virtual bool ContainsDtxOrCngPacket( 157 const DecoderDatabase* decoder_database) const; 158 159 // Static method returning true if `timestamp` is older than `timestamp_limit` 160 // but less than `horizon_samples` behind `timestamp_limit`. For instance, 161 // with timestamp_limit = 100 and horizon_samples = 10, a timestamp in the 162 // range (90, 100) is considered obsolete, and will yield true. 163 // Setting `horizon_samples` to 0 is the same as setting it to 2^31, i.e., 164 // half the 32-bit timestamp range. IsObsoleteTimestamp(uint32_t timestamp,uint32_t timestamp_limit,uint32_t horizon_samples)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 173 private: 174 absl::optional<SmartFlushingConfig> smart_flushing_config_; 175 size_t max_number_of_packets_; 176 PacketList buffer_; 177 const TickTimer* tick_timer_; 178 }; 179 180 } // namespace webrtc 181 #endif // MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_ 182