OLD | NEW |
| (Empty) |
1 /* | |
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 | |
11 #ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ | |
12 #define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ | |
13 | |
14 #include <map> | |
15 #include <vector> | |
16 | |
17 #include "webrtc/base/array_view.h" | |
18 #include "webrtc/base/optional.h" | |
19 #include "webrtc/base/scoped_ptr.h" | |
20 #include "webrtc/base/thread_annotations.h" | |
21 #include "webrtc/common_audio/vad/include/webrtc_vad.h" | |
22 #include "webrtc/engine_configurations.h" | |
23 #include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" | |
24 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" | |
25 #include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" | |
26 #include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" | |
27 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" | |
28 #include "webrtc/modules/include/module_common_types.h" | |
29 #include "webrtc/typedefs.h" | |
30 | |
31 namespace webrtc { | |
32 | |
33 struct CodecInst; | |
34 class CriticalSectionWrapper; | |
35 class NetEq; | |
36 | |
37 namespace acm2 { | |
38 | |
39 class AcmReceiver { | |
40 public: | |
41 struct Decoder { | |
42 int acm_codec_id; | |
43 uint8_t payload_type; | |
44 // This field is meaningful for codecs where both mono and | |
45 // stereo versions are registered under the same ID. | |
46 int channels; | |
47 int sample_rate_hz; | |
48 }; | |
49 | |
50 // Constructor of the class | |
51 explicit AcmReceiver(const AudioCodingModule::Config& config); | |
52 | |
53 // Destructor of the class. | |
54 ~AcmReceiver(); | |
55 | |
56 // | |
57 // Inserts a payload with its associated RTP-header into NetEq. | |
58 // | |
59 // Input: | |
60 // - rtp_header : RTP header for the incoming payload containing | |
61 // information about payload type, sequence number, | |
62 // timestamp, SSRC and marker bit. | |
63 // - incoming_payload : Incoming audio payload. | |
64 // - length_payload : Length of incoming audio payload in bytes. | |
65 // | |
66 // Return value : 0 if OK. | |
67 // <0 if NetEq returned an error. | |
68 // | |
69 int InsertPacket(const WebRtcRTPHeader& rtp_header, | |
70 rtc::ArrayView<const uint8_t> incoming_payload); | |
71 | |
72 // | |
73 // Asks NetEq for 10 milliseconds of decoded audio. | |
74 // | |
75 // Input: | |
76 // -desired_freq_hz : specifies the sampling rate [Hz] of the output | |
77 // audio. If set -1 indicates to resampling is | |
78 // is required and the audio returned at the | |
79 // sampling rate of the decoder. | |
80 // | |
81 // Output: | |
82 // -audio_frame : an audio frame were output data and | |
83 // associated parameters are written to. | |
84 // | |
85 // Return value : 0 if OK. | |
86 // -1 if NetEq returned an error. | |
87 // | |
88 int GetAudio(int desired_freq_hz, AudioFrame* audio_frame); | |
89 | |
90 // | |
91 // Adds a new codec to the NetEq codec database. | |
92 // | |
93 // Input: | |
94 // - acm_codec_id : ACM codec ID; -1 means external decoder. | |
95 // - payload_type : payload type. | |
96 // - sample_rate_hz : sample rate. | |
97 // - audio_decoder : pointer to a decoder object. If it's null, then | |
98 // NetEq will internally create a decoder object | |
99 // based on the value of |acm_codec_id| (which | |
100 // mustn't be -1). Otherwise, NetEq will use the | |
101 // given decoder for the given payload type. NetEq | |
102 // won't take ownership of the decoder; it's up to | |
103 // the caller to delete it when it's no longer | |
104 // needed. | |
105 // | |
106 // Providing an existing decoder object here is | |
107 // necessary for external decoders, but may also be | |
108 // used for built-in decoders if NetEq doesn't have | |
109 // all the info it needs to construct them properly | |
110 // (e.g. iSAC, where the decoder needs to be paired | |
111 // with an encoder). | |
112 // | |
113 // Return value : 0 if OK. | |
114 // <0 if NetEq returned an error. | |
115 // | |
116 int AddCodec(int acm_codec_id, | |
117 uint8_t payload_type, | |
118 int channels, | |
119 int sample_rate_hz, | |
120 AudioDecoder* audio_decoder); | |
121 | |
122 // | |
123 // Sets a minimum delay for packet buffer. The given delay is maintained, | |
124 // unless channel condition dictates a higher delay. | |
125 // | |
126 // Input: | |
127 // - delay_ms : minimum delay in milliseconds. | |
128 // | |
129 // Return value : 0 if OK. | |
130 // <0 if NetEq returned an error. | |
131 // | |
132 int SetMinimumDelay(int delay_ms); | |
133 | |
134 // | |
135 // Sets a maximum delay [ms] for the packet buffer. The target delay does not | |
136 // exceed the given value, even if channel condition requires so. | |
137 // | |
138 // Input: | |
139 // - delay_ms : maximum delay in milliseconds. | |
140 // | |
141 // Return value : 0 if OK. | |
142 // <0 if NetEq returned an error. | |
143 // | |
144 int SetMaximumDelay(int delay_ms); | |
145 | |
146 // | |
147 // Get least required delay computed based on channel conditions. Note that | |
148 // this is before applying any user-defined limits (specified by calling | |
149 // (SetMinimumDelay() and/or SetMaximumDelay()). | |
150 // | |
151 int LeastRequiredDelayMs() const; | |
152 | |
153 // | |
154 // Resets the initial delay to zero. | |
155 // | |
156 void ResetInitialDelay(); | |
157 | |
158 // Returns the sample rate of the decoder associated with the last incoming | |
159 // packet. If no packet of a registered non-CNG codec has been received, the | |
160 // return value is empty. Also, if the decoder was unregistered since the last | |
161 // packet was inserted, the return value is empty. | |
162 rtc::Optional<int> last_packet_sample_rate_hz() const; | |
163 | |
164 // Returns last_output_sample_rate_hz from the NetEq instance. | |
165 int last_output_sample_rate_hz() const; | |
166 | |
167 // | |
168 // Get the current network statistics from NetEq. | |
169 // | |
170 // Output: | |
171 // - statistics : The current network statistics. | |
172 // | |
173 void GetNetworkStatistics(NetworkStatistics* statistics); | |
174 | |
175 // | |
176 // Enable post-decoding VAD. | |
177 // | |
178 void EnableVad(); | |
179 | |
180 // | |
181 // Disable post-decoding VAD. | |
182 // | |
183 void DisableVad(); | |
184 | |
185 // | |
186 // Returns whether post-decoding VAD is enabled (true) or disabled (false). | |
187 // | |
188 bool vad_enabled() const { return vad_enabled_; } | |
189 | |
190 // | |
191 // Flushes the NetEq packet and speech buffers. | |
192 // | |
193 void FlushBuffers(); | |
194 | |
195 // | |
196 // Removes a payload-type from the NetEq codec database. | |
197 // | |
198 // Input: | |
199 // - payload_type : the payload-type to be removed. | |
200 // | |
201 // Return value : 0 if OK. | |
202 // -1 if an error occurred. | |
203 // | |
204 int RemoveCodec(uint8_t payload_type); | |
205 | |
206 // | |
207 // Remove all registered codecs. | |
208 // | |
209 int RemoveAllCodecs(); | |
210 | |
211 // | |
212 // Set ID. | |
213 // | |
214 void set_id(int id); // TODO(turajs): can be inline. | |
215 | |
216 // | |
217 // Gets the RTP timestamp of the last sample delivered by GetAudio(). | |
218 // Returns true if the RTP timestamp is valid, otherwise false. | |
219 // | |
220 bool GetPlayoutTimestamp(uint32_t* timestamp); | |
221 | |
222 // | |
223 // Get the audio codec associated with the last non-CNG/non-DTMF received | |
224 // payload. If no non-CNG/non-DTMF packet is received -1 is returned, | |
225 // otherwise return 0. | |
226 // | |
227 int LastAudioCodec(CodecInst* codec) const; | |
228 | |
229 // | |
230 // Get a decoder given its registered payload-type. | |
231 // | |
232 // Input: | |
233 // -payload_type : the payload-type of the codec to be retrieved. | |
234 // | |
235 // Output: | |
236 // -codec : codec associated with the given payload-type. | |
237 // | |
238 // Return value : 0 if succeeded. | |
239 // -1 if failed, e.g. given payload-type is not | |
240 // registered. | |
241 // | |
242 int DecoderByPayloadType(uint8_t payload_type, | |
243 CodecInst* codec) const; | |
244 | |
245 // | |
246 // Enable NACK and set the maximum size of the NACK list. If NACK is already | |
247 // enabled then the maximum NACK list size is modified accordingly. | |
248 // | |
249 // Input: | |
250 // -max_nack_list_size : maximum NACK list size | |
251 // should be positive (none zero) and less than or | |
252 // equal to |Nack::kNackListSizeLimit| | |
253 // Return value | |
254 // : 0 if succeeded. | |
255 // -1 if failed | |
256 // | |
257 int EnableNack(size_t max_nack_list_size); | |
258 | |
259 // Disable NACK. | |
260 void DisableNack(); | |
261 | |
262 // | |
263 // Get a list of packets to be retransmitted. | |
264 // | |
265 // Input: | |
266 // -round_trip_time_ms : estimate of the round-trip-time (in milliseconds). | |
267 // Return value : list of packets to be retransmitted. | |
268 // | |
269 std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const; | |
270 | |
271 // | |
272 // Get statistics of calls to GetAudio(). | |
273 void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; | |
274 | |
275 private: | |
276 const Decoder* RtpHeaderToDecoder(const RTPHeader& rtp_header, | |
277 uint8_t payload_type) const | |
278 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); | |
279 | |
280 uint32_t NowInTimestamp(int decoder_sampling_rate) const; | |
281 | |
282 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; | |
283 int id_; // TODO(henrik.lundin) Make const. | |
284 const Decoder* last_audio_decoder_ GUARDED_BY(crit_sect_); | |
285 AudioFrame::VADActivity previous_audio_activity_ GUARDED_BY(crit_sect_); | |
286 ACMResampler resampler_ GUARDED_BY(crit_sect_); | |
287 // Used in GetAudio, declared as member to avoid allocating every 10ms. | |
288 // TODO(henrik.lundin) Stack-allocate in GetAudio instead? | |
289 rtc::scoped_ptr<int16_t[]> audio_buffer_ GUARDED_BY(crit_sect_); | |
290 rtc::scoped_ptr<int16_t[]> last_audio_buffer_ GUARDED_BY(crit_sect_); | |
291 CallStatistics call_stats_ GUARDED_BY(crit_sect_); | |
292 NetEq* neteq_; | |
293 // Decoders map is keyed by payload type | |
294 std::map<uint8_t, Decoder> decoders_ GUARDED_BY(crit_sect_); | |
295 bool vad_enabled_; | |
296 Clock* clock_; // TODO(henrik.lundin) Make const if possible. | |
297 bool resampled_last_output_frame_ GUARDED_BY(crit_sect_); | |
298 rtc::Optional<int> last_packet_sample_rate_hz_ GUARDED_BY(crit_sect_); | |
299 }; | |
300 | |
301 } // namespace acm2 | |
302 | |
303 } // namespace webrtc | |
304 | |
305 #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ | |
OLD | NEW |