OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 101 |
102 bool CodecSupported(const CodecInst& codec) { | 102 bool CodecSupported(const CodecInst& codec) { |
103 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || | 103 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || |
104 IsIlbc(codec) || IsG722(codec) || IsIsac(codec); | 104 IsIlbc(codec) || IsG722(codec) || IsIsac(codec); |
105 } | 105 } |
106 | 106 |
107 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; | 107 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; |
108 } // namespace | 108 } // namespace |
109 | 109 |
110 CodecManager::CodecManager() | 110 CodecManager::CodecManager() |
111 : dtx_enabled_(false), | 111 : send_codec_inst_(kEmptyCodecInst), encoder_is_opus_(false) { |
112 vad_mode_(VADNormal), | |
113 send_codec_inst_(kEmptyCodecInst), | |
114 red_enabled_(false), | |
115 codec_fec_enabled_(false), | |
116 encoder_is_opus_(false) { | |
117 // Register the default payload types for RED and CNG. | |
118 for (const CodecInst& ci : RentACodec::Database()) { | |
119 RentACodec::RegisterCngPayloadType(&cng_payload_types_, ci); | |
120 RentACodec::RegisterRedPayloadType(&red_payload_types_, ci); | |
121 } | |
122 thread_checker_.DetachFromThread(); | 112 thread_checker_.DetachFromThread(); |
123 } | 113 } |
124 | 114 |
125 CodecManager::~CodecManager() = default; | 115 CodecManager::~CodecManager() = default; |
126 | 116 |
127 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { | 117 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { |
128 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 118 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
129 int codec_id = IsValidSendCodec(send_codec); | 119 int codec_id = IsValidSendCodec(send_codec); |
130 | 120 |
131 // Check for reported errors from function IsValidSendCodec(). | 121 // Check for reported errors from function IsValidSendCodec(). |
132 if (codec_id < 0) { | 122 if (codec_id < 0) { |
133 return -1; | 123 return -1; |
134 } | 124 } |
135 | 125 |
136 int dummy_id = 0; | 126 int dummy_id = 0; |
137 switch (RentACodec::RegisterRedPayloadType(&red_payload_types_, send_codec)) { | 127 switch (RentACodec::RegisterRedPayloadType( |
| 128 &codec_stack_params_.red_payload_types, send_codec)) { |
138 case RentACodec::RegistrationResult::kOk: | 129 case RentACodec::RegistrationResult::kOk: |
139 return 0; | 130 return 0; |
140 case RentACodec::RegistrationResult::kBadFreq: | 131 case RentACodec::RegistrationResult::kBadFreq: |
141 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 132 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, |
142 "RegisterSendCodec() failed, invalid frequency for RED" | 133 "RegisterSendCodec() failed, invalid frequency for RED" |
143 " registration"); | 134 " registration"); |
144 return -1; | 135 return -1; |
145 case RentACodec::RegistrationResult::kSkip: | 136 case RentACodec::RegistrationResult::kSkip: |
146 break; | 137 break; |
147 } | 138 } |
148 switch (RentACodec::RegisterCngPayloadType(&cng_payload_types_, send_codec)) { | 139 switch (RentACodec::RegisterCngPayloadType( |
| 140 &codec_stack_params_.cng_payload_types, send_codec)) { |
149 case RentACodec::RegistrationResult::kOk: | 141 case RentACodec::RegistrationResult::kOk: |
150 return 0; | 142 return 0; |
151 case RentACodec::RegistrationResult::kBadFreq: | 143 case RentACodec::RegistrationResult::kBadFreq: |
152 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 144 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, |
153 "RegisterSendCodec() failed, invalid frequency for CNG" | 145 "RegisterSendCodec() failed, invalid frequency for CNG" |
154 " registration"); | 146 " registration"); |
155 return -1; | 147 return -1; |
156 case RentACodec::RegistrationResult::kSkip: | 148 case RentACodec::RegistrationResult::kSkip: |
157 break; | 149 break; |
158 } | 150 } |
159 | 151 |
160 // Set Stereo, and make sure VAD and DTX is turned off. | 152 // Set Stereo, and make sure VAD and DTX is turned off. |
161 if (send_codec.channels != 1) { | 153 if (send_codec.channels != 1) { |
162 if (dtx_enabled_) { | 154 if (codec_stack_params_.use_cng) { |
163 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, | 155 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, |
164 "VAD/DTX is turned off, not supported when sending stereo."); | 156 "VAD/DTX is turned off, not supported when sending stereo."); |
165 } | 157 } |
166 dtx_enabled_ = false; | 158 codec_stack_params_.use_cng = false; |
167 } | 159 } |
168 | 160 |
169 // Check if the codec is already registered as send codec. | 161 // Check if the codec is already registered as send codec. |
170 bool new_codec = true; | 162 bool new_codec = true; |
171 if (CurrentEncoder()) { | 163 if (CurrentEncoder()) { |
172 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); | 164 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); |
173 RTC_DCHECK(new_codec_id); | 165 RTC_DCHECK(new_codec_id); |
174 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); | 166 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); |
175 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; | 167 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; |
176 } | 168 } |
177 | 169 |
178 if (RedPayloadType(send_codec.plfreq) == -1) { | |
179 red_enabled_ = false; | |
180 } | |
181 | |
182 encoder_is_opus_ = IsOpus(send_codec); | 170 encoder_is_opus_ = IsOpus(send_codec); |
183 | 171 |
184 if (new_codec) { | 172 if (new_codec) { |
185 // This is a new codec. Register it and return. | 173 // This is a new codec. Register it and return. |
186 RTC_DCHECK(CodecSupported(send_codec)); | 174 RTC_DCHECK(CodecSupported(send_codec)); |
187 if (IsOpus(send_codec)) { | 175 if (IsOpus(send_codec)) { |
188 // VAD/DTX not supported. | 176 // VAD/DTX not supported. |
189 dtx_enabled_ = false; | 177 codec_stack_params_.use_cng = false; |
190 } | 178 } |
191 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 179 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
192 if (!enc) | 180 if (!enc) |
193 return -1; | 181 return -1; |
194 RentEncoderStack(enc, send_codec.plfreq); | 182 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_); |
195 RTC_DCHECK(CurrentEncoder()); | 183 RTC_DCHECK(CurrentEncoder()); |
196 | 184 |
197 codec_fec_enabled_ = codec_fec_enabled_ && | 185 codec_stack_params_.use_codec_fec = |
198 enc->SetFec(codec_fec_enabled_); | 186 codec_stack_params_.use_codec_fec && |
| 187 enc->SetFec(codec_stack_params_.use_codec_fec); |
199 | 188 |
200 send_codec_inst_ = send_codec; | 189 send_codec_inst_ = send_codec; |
201 return 0; | 190 return 0; |
202 } | 191 } |
203 | 192 |
204 // This is an existing codec; re-create it if any parameters have changed. | 193 // This is an existing codec; re-create it if any parameters have changed. |
205 if (send_codec_inst_.plfreq != send_codec.plfreq || | 194 if (send_codec_inst_.plfreq != send_codec.plfreq || |
206 send_codec_inst_.pacsize != send_codec.pacsize || | 195 send_codec_inst_.pacsize != send_codec.pacsize || |
207 send_codec_inst_.channels != send_codec.channels) { | 196 send_codec_inst_.channels != send_codec.channels) { |
208 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 197 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
209 if (!enc) | 198 if (!enc) |
210 return -1; | 199 return -1; |
211 RentEncoderStack(enc, send_codec.plfreq); | 200 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_); |
212 RTC_DCHECK(CurrentEncoder()); | 201 RTC_DCHECK(CurrentEncoder()); |
213 } | 202 } |
214 send_codec_inst_.plfreq = send_codec.plfreq; | 203 send_codec_inst_.plfreq = send_codec.plfreq; |
215 send_codec_inst_.pacsize = send_codec.pacsize; | 204 send_codec_inst_.pacsize = send_codec.pacsize; |
216 send_codec_inst_.channels = send_codec.channels; | 205 send_codec_inst_.channels = send_codec.channels; |
217 send_codec_inst_.pltype = send_codec.pltype; | 206 send_codec_inst_.pltype = send_codec.pltype; |
218 | 207 |
219 // Check if a change in Rate is required. | 208 // Check if a change in Rate is required. |
220 if (send_codec.rate != send_codec_inst_.rate) { | 209 if (send_codec.rate != send_codec_inst_.rate) { |
221 CurrentEncoder()->SetTargetBitrate(send_codec.rate); | 210 CurrentEncoder()->SetTargetBitrate(send_codec.rate); |
222 send_codec_inst_.rate = send_codec.rate; | 211 send_codec_inst_.rate = send_codec.rate; |
223 } | 212 } |
224 | 213 |
225 codec_fec_enabled_ = | 214 codec_stack_params_.use_codec_fec = |
226 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_); | 215 codec_stack_params_.use_codec_fec && |
| 216 CurrentEncoder()->SetFec(codec_stack_params_.use_codec_fec); |
227 | 217 |
228 return 0; | 218 return 0; |
229 } | 219 } |
230 | 220 |
231 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { | 221 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { |
232 // Make up a CodecInst. | 222 // Make up a CodecInst. |
233 send_codec_inst_.channels = external_speech_encoder->NumChannels(); | 223 send_codec_inst_.channels = external_speech_encoder->NumChannels(); |
234 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); | 224 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); |
235 send_codec_inst_.pacsize = rtc::CheckedDivExact( | 225 send_codec_inst_.pacsize = rtc::CheckedDivExact( |
236 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * | 226 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * |
237 send_codec_inst_.plfreq), | 227 send_codec_inst_.plfreq), |
238 100); | 228 100); |
239 send_codec_inst_.pltype = -1; // Not valid. | 229 send_codec_inst_.pltype = -1; // Not valid. |
240 send_codec_inst_.rate = -1; // Not valid. | 230 send_codec_inst_.rate = -1; // Not valid. |
241 static const char kName[] = "external"; | 231 static const char kName[] = "external"; |
242 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); | 232 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); |
243 | 233 |
244 if (send_codec_inst_.channels != 1) | 234 if (send_codec_inst_.channels != 1) |
245 dtx_enabled_ = false; | 235 codec_stack_params_.use_cng = false; |
246 if (codec_fec_enabled_) { | 236 if (codec_stack_params_.use_codec_fec) { |
247 // Switch FEC on. On failure, remember that FEC is off. | 237 // Switch FEC on. On failure, remember that FEC is off. |
248 if (!external_speech_encoder->SetFec(true)) | 238 if (!external_speech_encoder->SetFec(true)) |
249 codec_fec_enabled_ = false; | 239 codec_stack_params_.use_codec_fec = false; |
250 } else { | 240 } else { |
251 // Switch FEC off. This shouldn't fail. | 241 // Switch FEC off. This shouldn't fail. |
252 const bool success = external_speech_encoder->SetFec(false); | 242 const bool success = external_speech_encoder->SetFec(false); |
253 RTC_DCHECK(success); | 243 RTC_DCHECK(success); |
254 } | 244 } |
255 | 245 |
256 RentEncoderStack(external_speech_encoder, | 246 rent_a_codec_.RentEncoderStack(external_speech_encoder, &codec_stack_params_); |
257 external_speech_encoder->SampleRateHz()); | |
258 } | 247 } |
259 | 248 |
260 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { | 249 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { |
261 int dummy_id = 0; | 250 int dummy_id = 0; |
262 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 251 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
263 "SendCodec()"); | 252 "SendCodec()"); |
264 | 253 |
265 if (!CurrentEncoder()) { | 254 if (!CurrentEncoder()) { |
266 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 255 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
267 "SendCodec Failed, no codec is registered"); | 256 "SendCodec Failed, no codec is registered"); |
268 return rtc::Optional<CodecInst>(); | 257 return rtc::Optional<CodecInst>(); |
269 } | 258 } |
270 return rtc::Optional<CodecInst>(send_codec_inst_); | 259 return rtc::Optional<CodecInst>(send_codec_inst_); |
271 } | 260 } |
272 | 261 |
273 bool CodecManager::SetCopyRed(bool enable) { | 262 bool CodecManager::SetCopyRed(bool enable) { |
274 if (enable && codec_fec_enabled_) { | 263 if (enable && codec_stack_params_.use_codec_fec) { |
275 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 264 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
276 "Codec internal FEC and RED cannot be co-enabled."); | 265 "Codec internal FEC and RED cannot be co-enabled."); |
277 return false; | 266 return false; |
278 } | 267 } |
279 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { | 268 if (enable && |
| 269 codec_stack_params_.red_payload_types.count(send_codec_inst_.plfreq) < |
| 270 1) { |
280 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 271 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
281 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); | 272 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); |
282 return false; | 273 return false; |
283 } | 274 } |
284 if (red_enabled_ != enable) { | 275 if (codec_stack_params_.use_red != enable) { |
285 red_enabled_ = enable; | 276 codec_stack_params_.use_red = enable; |
286 if (CurrentEncoder()) | 277 if (CurrentEncoder()) |
287 RentEncoderStack(rent_a_codec_.GetEncoder(), send_codec_inst_.plfreq); | 278 rent_a_codec_.RentEncoderStack(rent_a_codec_.GetEncoder(), |
| 279 &codec_stack_params_); |
288 } | 280 } |
289 return true; | 281 return true; |
290 } | 282 } |
291 | 283 |
292 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 284 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { |
293 // Sanity check of the mode. | 285 // Sanity check of the mode. |
294 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || | 286 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || |
295 mode == VADVeryAggr); | 287 mode == VADVeryAggr); |
296 | 288 |
297 // Check that the send codec is mono. We don't support VAD/DTX for stereo | 289 // Check that the send codec is mono. We don't support VAD/DTX for stereo |
298 // sending. | 290 // sending. |
299 auto* enc = rent_a_codec_.GetEncoder(); | 291 auto* enc = rent_a_codec_.GetEncoder(); |
300 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; | 292 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; |
301 if (enable && stereo_send) { | 293 if (enable && stereo_send) { |
302 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, | 294 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, |
303 "VAD/DTX not supported for stereo sending"); | 295 "VAD/DTX not supported for stereo sending"); |
304 dtx_enabled_ = false; | 296 codec_stack_params_.use_cng = false; |
305 return -1; | 297 return -1; |
306 } | 298 } |
307 | 299 |
308 // If a send codec is registered, set VAD/DTX for the codec. | 300 // If a send codec is registered, set VAD/DTX for the codec. |
309 if (IsOpus(send_codec_inst_)) { | 301 if (IsOpus(send_codec_inst_)) { |
310 // VAD/DTX not supported. | 302 // VAD/DTX not supported. |
311 dtx_enabled_ = false; | 303 codec_stack_params_.use_cng = false; |
312 return 0; | 304 return 0; |
313 } | 305 } |
314 | 306 |
315 if (dtx_enabled_ != enable || vad_mode_ != mode) { | 307 if (codec_stack_params_.use_cng != enable || |
316 dtx_enabled_ = enable; | 308 codec_stack_params_.vad_mode != mode) { |
317 vad_mode_ = mode; | 309 codec_stack_params_.use_cng = enable; |
| 310 codec_stack_params_.vad_mode = mode; |
318 if (enc) | 311 if (enc) |
319 RentEncoderStack(enc, send_codec_inst_.plfreq); | 312 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_); |
320 } | 313 } |
321 return 0; | 314 return 0; |
322 } | 315 } |
323 | 316 |
324 void CodecManager::VAD(bool* dtx_enabled, | 317 void CodecManager::VAD(bool* dtx_enabled, |
325 bool* vad_enabled, | 318 bool* vad_enabled, |
326 ACMVADMode* mode) const { | 319 ACMVADMode* mode) const { |
327 *dtx_enabled = dtx_enabled_; | 320 *dtx_enabled = *vad_enabled = codec_stack_params_.use_cng; |
328 *vad_enabled = dtx_enabled_; | 321 *mode = codec_stack_params_.vad_mode; |
329 *mode = vad_mode_; | |
330 } | 322 } |
331 | 323 |
332 int CodecManager::SetCodecFEC(bool enable_codec_fec) { | 324 int CodecManager::SetCodecFEC(bool enable_codec_fec) { |
333 if (enable_codec_fec == true && red_enabled_ == true) { | 325 if (enable_codec_fec && codec_stack_params_.use_red) { |
334 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 326 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
335 "Codec internal FEC and RED cannot be co-enabled."); | 327 "Codec internal FEC and RED cannot be co-enabled."); |
336 return -1; | 328 return -1; |
337 } | 329 } |
338 | 330 |
339 RTC_CHECK(CurrentEncoder()); | 331 RTC_CHECK(CurrentEncoder()); |
340 codec_fec_enabled_ = | 332 codec_stack_params_.use_codec_fec = |
341 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; | 333 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; |
342 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; | 334 return codec_stack_params_.use_codec_fec == enable_codec_fec ? 0 : -1; |
343 } | 335 } |
344 | 336 |
345 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { | 337 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { |
346 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; | 338 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; |
347 } | 339 } |
348 | 340 |
349 int CodecManager::CngPayloadType(int rtp_timestamp_rate_hz) const { | |
350 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 || | |
351 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000) | |
352 << rtp_timestamp_rate_hz << " Hz is not supported"; | |
353 auto it = cng_payload_types_.find(rtp_timestamp_rate_hz); | |
354 return it == cng_payload_types_.end() ? -1 : it->second; | |
355 } | |
356 | |
357 int CodecManager::RedPayloadType(int rtp_timestamp_rate_hz) const { | |
358 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 || | |
359 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000) | |
360 << rtp_timestamp_rate_hz << " Hz is not supported"; | |
361 auto it = red_payload_types_.find(rtp_timestamp_rate_hz); | |
362 return it == red_payload_types_.end() ? -1 : it->second; | |
363 } | |
364 | |
365 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder, | |
366 int sample_rate_hz) { | |
367 auto cng_config = | |
368 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ | |
369 CngPayloadType(sample_rate_hz), vad_mode_}) | |
370 : rtc::Optional<RentACodec::CngConfig>(); | |
371 auto red_pt = red_enabled_ | |
372 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz)) | |
373 : rtc::Optional<int>(); | |
374 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt); | |
375 } | |
376 | |
377 } // namespace acm2 | 341 } // namespace acm2 |
378 } // namespace webrtc | 342 } // namespace webrtc |
OLD | NEW |