blob: f133a873c26f86ff03a1498578049e155affc2e9 [file] [log] [blame]
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001/*
2 * Copyright (c) 2013 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_ACM2_ACM_RECEIVER_H_
12#define MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
turaj@webrtc.org7959e162013-09-12 18:30:26 +000013
jmarusic@webrtc.orga4bef3e2015-03-23 11:19:35 +000014#include <map>
kwiberg16c5a962016-02-15 02:27:22 -080015#include <memory>
henrik.lundin4cf61dd2015-12-09 06:20:58 -080016#include <string>
turaj@webrtc.org7959e162013-09-12 18:30:26 +000017#include <vector>
18
Danil Chapovalovb6021232018-06-19 13:26:36 +020019#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/array_view.h"
Danil Chapovalovb6021232018-06-19 13:26:36 +020021#include "api/audio/audio_frame.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "common_audio/vad/include/webrtc_vad.h"
23#include "modules/audio_coding/acm2/acm_resampler.h"
24#include "modules/audio_coding/acm2/call_statistics.h"
25#include "modules/audio_coding/include/audio_coding_module.h"
26#include "modules/audio_coding/neteq/include/neteq.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "rtc_base/criticalsection.h"
28#include "rtc_base/thread_annotations.h"
turaj@webrtc.org7959e162013-09-12 18:30:26 +000029
30namespace webrtc {
31
turaj@webrtc.org6d5d2482013-10-06 04:47:28 +000032struct CodecInst;
turaj@webrtc.org7959e162013-09-12 18:30:26 +000033class NetEq;
turaj@webrtc.org6d5d2482013-10-06 04:47:28 +000034
35namespace acm2 {
36
turaj@webrtc.org7959e162013-09-12 18:30:26 +000037class AcmReceiver {
38 public:
turaj@webrtc.org7959e162013-09-12 18:30:26 +000039 // Constructor of the class
henrik.lundin@webrtc.org0bc9b5a2014-04-29 08:09:31 +000040 explicit AcmReceiver(const AudioCodingModule::Config& config);
turaj@webrtc.org7959e162013-09-12 18:30:26 +000041
42 // Destructor of the class.
43 ~AcmReceiver();
44
45 //
46 // Inserts a payload with its associated RTP-header into NetEq.
47 //
48 // Input:
49 // - rtp_header : RTP header for the incoming payload containing
50 // information about payload type, sequence number,
51 // timestamp, SSRC and marker bit.
52 // - incoming_payload : Incoming audio payload.
53 // - length_payload : Length of incoming audio payload in bytes.
54 //
55 // Return value : 0 if OK.
56 // <0 if NetEq returned an error.
57 //
58 int InsertPacket(const WebRtcRTPHeader& rtp_header,
kwibergee2bac22015-11-11 10:34:00 -080059 rtc::ArrayView<const uint8_t> incoming_payload);
turaj@webrtc.org7959e162013-09-12 18:30:26 +000060
61 //
62 // Asks NetEq for 10 milliseconds of decoded audio.
63 //
64 // Input:
65 // -desired_freq_hz : specifies the sampling rate [Hz] of the output
66 // audio. If set -1 indicates to resampling is
67 // is required and the audio returned at the
68 // sampling rate of the decoder.
69 //
70 // Output:
71 // -audio_frame : an audio frame were output data and
72 // associated parameters are written to.
henrik.lundin834a6ea2016-05-13 03:45:24 -070073 // -muted : if true, the sample data in audio_frame is not
74 // populated, and must be interpreted as all zero.
turaj@webrtc.org7959e162013-09-12 18:30:26 +000075 //
76 // Return value : 0 if OK.
77 // -1 if NetEq returned an error.
78 //
henrik.lundin834a6ea2016-05-13 03:45:24 -070079 int GetAudio(int desired_freq_hz, AudioFrame* audio_frame, bool* muted);
turaj@webrtc.org7959e162013-09-12 18:30:26 +000080
kwiberg1c07c702017-03-27 07:15:49 -070081 // Replace the current set of decoders with the specified set.
82 void SetCodecs(const std::map<int, SdpAudioFormat>& codecs);
83
turaj@webrtc.org7959e162013-09-12 18:30:26 +000084 //
85 // Adds a new codec to the NetEq codec database.
86 //
87 // Input:
kwiberg4e14f092015-08-24 05:27:22 -070088 // - acm_codec_id : ACM codec ID; -1 means external decoder.
turaj@webrtc.org7959e162013-09-12 18:30:26 +000089 // - payload_type : payload type.
Karl Wibergd8399e62015-05-25 14:39:56 +020090 // - sample_rate_hz : sample rate.
kwiberg4e14f092015-08-24 05:27:22 -070091 // - audio_decoder : pointer to a decoder object. If it's null, then
92 // NetEq will internally create a decoder object
93 // based on the value of |acm_codec_id| (which
94 // mustn't be -1). Otherwise, NetEq will use the
95 // given decoder for the given payload type. NetEq
96 // won't take ownership of the decoder; it's up to
97 // the caller to delete it when it's no longer
98 // needed.
99 //
100 // Providing an existing decoder object here is
101 // necessary for external decoders, but may also be
102 // used for built-in decoders if NetEq doesn't have
103 // all the info it needs to construct them properly
104 // (e.g. iSAC, where the decoder needs to be paired
105 // with an encoder).
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000106 //
107 // Return value : 0 if OK.
108 // <0 if NetEq returned an error.
109 //
110 int AddCodec(int acm_codec_id,
111 uint8_t payload_type,
Peter Kasting69558702016-01-12 16:26:35 -0800112 size_t channels,
Karl Wibergd8399e62015-05-25 14:39:56 +0200113 int sample_rate_hz,
henrik.lundin4cf61dd2015-12-09 06:20:58 -0800114 AudioDecoder* audio_decoder,
115 const std::string& name);
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000116
kwiberg5adaf732016-10-04 09:33:27 -0700117 // Adds a new decoder to the NetEq codec database. Returns true iff
118 // successful.
119 bool AddCodec(int rtp_payload_type, const SdpAudioFormat& audio_format);
120
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000121 //
122 // Sets a minimum delay for packet buffer. The given delay is maintained,
123 // unless channel condition dictates a higher delay.
124 //
125 // Input:
126 // - delay_ms : minimum delay in milliseconds.
127 //
128 // Return value : 0 if OK.
129 // <0 if NetEq returned an error.
130 //
131 int SetMinimumDelay(int delay_ms);
132
133 //
134 // Sets a maximum delay [ms] for the packet buffer. The target delay does not
135 // exceed the given value, even if channel condition requires so.
136 //
137 // Input:
138 // - delay_ms : maximum delay in milliseconds.
139 //
140 // Return value : 0 if OK.
141 // <0 if NetEq returned an error.
142 //
143 int SetMaximumDelay(int delay_ms);
144
145 //
146 // Get least required delay computed based on channel conditions. Note that
147 // this is before applying any user-defined limits (specified by calling
148 // (SetMinimumDelay() and/or SetMaximumDelay()).
149 //
150 int LeastRequiredDelayMs() const;
151
152 //
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000153 // Resets the initial delay to zero.
154 //
155 void ResetInitialDelay();
156
henrik.lundin057fb892015-11-23 08:19:52 -0800157 // Returns the sample rate of the decoder associated with the last incoming
158 // packet. If no packet of a registered non-CNG codec has been received, the
159 // return value is empty. Also, if the decoder was unregistered since the last
160 // packet was inserted, the return value is empty.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200161 absl::optional<int> last_packet_sample_rate_hz() const;
henrik.lundin057fb892015-11-23 08:19:52 -0800162
henrik.lundind89814b2015-11-23 06:49:25 -0800163 // Returns last_output_sample_rate_hz from the NetEq instance.
164 int last_output_sample_rate_hz() const;
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000165
166 //
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000167 // Get the current network statistics from NetEq.
168 //
169 // Output:
170 // - statistics : The current network statistics.
171 //
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000172 void GetNetworkStatistics(NetworkStatistics* statistics);
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000173
174 //
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000175 // Flushes the NetEq packet and speech buffers.
176 //
177 void FlushBuffers();
178
179 //
180 // Removes a payload-type from the NetEq codec database.
181 //
182 // Input:
183 // - payload_type : the payload-type to be removed.
184 //
185 // Return value : 0 if OK.
186 // -1 if an error occurred.
187 //
188 int RemoveCodec(uint8_t payload_type);
189
190 //
191 // Remove all registered codecs.
192 //
kwiberg6b19b562016-09-20 04:02:25 -0700193 void RemoveAllCodecs();
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000194
henrik.lundin9a410dd2016-04-06 01:39:22 -0700195 // Returns the RTP timestamp for the last sample delivered by GetAudio().
196 // The return value will be empty if no valid timestamp is available.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200197 absl::optional<uint32_t> GetPlayoutTimestamp();
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000198
henrik.lundinb3f1c5d2016-08-22 15:39:53 -0700199 // Returns the current total delay from NetEq (packet buffer and sync buffer)
200 // in ms, with smoothing applied to even out short-time fluctuations due to
201 // jitter. The packet buffer part of the delay is not updated during DTX/CNG
202 // periods.
203 //
204 int FilteredCurrentDelayMs() const;
205
Henrik Lundinabbff892017-11-29 09:14:04 +0100206 // Returns the current target delay for NetEq in ms.
207 //
208 int TargetDelayMs() const;
209
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000210 //
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000211 // Get the audio codec associated with the last non-CNG/non-DTMF received
212 // payload. If no non-CNG/non-DTMF packet is received -1 is returned,
213 // otherwise return 0.
214 //
215 int LastAudioCodec(CodecInst* codec) const;
216
Danil Chapovalovb6021232018-06-19 13:26:36 +0200217 absl::optional<SdpAudioFormat> LastAudioFormat() const;
ossue280cde2016-10-12 11:04:10 -0700218
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000219 //
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000220 // Get a decoder given its registered payload-type.
221 //
222 // Input:
223 // -payload_type : the payload-type of the codec to be retrieved.
224 //
225 // Output:
226 // -codec : codec associated with the given payload-type.
227 //
228 // Return value : 0 if succeeded.
229 // -1 if failed, e.g. given payload-type is not
230 // registered.
231 //
232 int DecoderByPayloadType(uint8_t payload_type,
233 CodecInst* codec) const;
234
235 //
236 // Enable NACK and set the maximum size of the NACK list. If NACK is already
237 // enabled then the maximum NACK list size is modified accordingly.
238 //
239 // Input:
240 // -max_nack_list_size : maximum NACK list size
241 // should be positive (none zero) and less than or
242 // equal to |Nack::kNackListSizeLimit|
243 // Return value
244 // : 0 if succeeded.
245 // -1 if failed
246 //
247 int EnableNack(size_t max_nack_list_size);
248
249 // Disable NACK.
250 void DisableNack();
251
252 //
253 // Get a list of packets to be retransmitted.
254 //
255 // Input:
256 // -round_trip_time_ms : estimate of the round-trip-time (in milliseconds).
257 // Return value : list of packets to be retransmitted.
258 //
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000259 std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const;
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000260
261 //
wu@webrtc.org24301a62013-12-13 19:17:43 +0000262 // Get statistics of calls to GetAudio().
263 void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const;
264
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000265 private:
kwiberg6f0f6162016-09-20 03:07:46 -0700266 struct Decoder {
267 int acm_codec_id;
268 uint8_t payload_type;
269 // This field is meaningful for codecs where both mono and
270 // stereo versions are registered under the same ID.
271 size_t channels;
272 int sample_rate_hz;
273 };
274
Danil Chapovalovb6021232018-06-19 13:26:36 +0200275 const absl::optional<CodecInst> RtpHeaderToDecoder(
276 const RTPHeader& rtp_header,
277 uint8_t first_payload_byte) const
278 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000279
280 uint32_t NowInTimestamp(int decoder_sampling_rate) const;
281
pbos5ad935c2016-01-25 03:52:44 -0800282 rtc::CriticalSection crit_sect_;
Danil Chapovalovb6021232018-06-19 13:26:36 +0200283 absl::optional<CodecInst> last_audio_decoder_ RTC_GUARDED_BY(crit_sect_);
284 absl::optional<SdpAudioFormat> last_audio_format_ RTC_GUARDED_BY(crit_sect_);
danilchap56359be2017-09-07 07:53:45 -0700285 ACMResampler resampler_ RTC_GUARDED_BY(crit_sect_);
286 std::unique_ptr<int16_t[]> last_audio_buffer_ RTC_GUARDED_BY(crit_sect_);
287 CallStatistics call_stats_ RTC_GUARDED_BY(crit_sect_);
Henrik Lundin6af93992017-06-14 14:13:02 +0200288 const std::unique_ptr<NetEq> neteq_; // NetEq is thread-safe; no lock needed.
Henrik Lundin02ed2012017-06-08 09:03:55 +0200289 const Clock* const clock_;
danilchap56359be2017-09-07 07:53:45 -0700290 bool resampled_last_output_frame_ RTC_GUARDED_BY(crit_sect_);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200291 absl::optional<int> last_packet_sample_rate_hz_ RTC_GUARDED_BY(crit_sect_);
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000292};
293
turaj@webrtc.org6d5d2482013-10-06 04:47:28 +0000294} // namespace acm2
295
turaj@webrtc.org7959e162013-09-12 18:30:26 +0000296} // namespace webrtc
297
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200298#endif // MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_