| 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 |