Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: webrtc/modules/audio_coding/acm2/codec_manager.cc

Issue 1520283006: Move Rent-A-Codec out of CodecManager (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@rac0
Patch Set: review comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 if (!RentACodec::IsSupportedNumChannels(*maybe_codec_id, send_codec.channels) 48 if (!RentACodec::IsSupportedNumChannels(*maybe_codec_id, send_codec.channels)
49 .value_or(false)) { 49 .value_or(false)) {
50 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, 50 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id,
51 "%d number of channels not supportedn for %s.", 51 "%d number of channels not supportedn for %s.",
52 send_codec.channels, send_codec.plname); 52 send_codec.channels, send_codec.plname);
53 return -1; 53 return -1;
54 } 54 }
55 return RentACodec::CodecIndexFromId(*maybe_codec_id).value_or(-1); 55 return RentACodec::CodecIndexFromId(*maybe_codec_id).value_or(-1);
56 } 56 }
57 57
58 bool IsIsac(const CodecInst& codec) {
59 return
60 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
61 !STR_CASE_CMP(codec.plname, "isac") ||
62 #endif
63 false;
64 }
65
66 bool IsOpus(const CodecInst& codec) { 58 bool IsOpus(const CodecInst& codec) {
67 return 59 return
68 #ifdef WEBRTC_CODEC_OPUS 60 #ifdef WEBRTC_CODEC_OPUS
69 !STR_CASE_CMP(codec.plname, "opus") || 61 !STR_CASE_CMP(codec.plname, "opus") ||
70 #endif 62 #endif
71 false; 63 false;
72 } 64 }
73 65
74 bool IsPcmU(const CodecInst& codec) {
75 return !STR_CASE_CMP(codec.plname, "pcmu");
76 }
77
78 bool IsPcmA(const CodecInst& codec) {
79 return !STR_CASE_CMP(codec.plname, "pcma");
80 }
81
82 bool IsPcm16B(const CodecInst& codec) {
83 return !STR_CASE_CMP(codec.plname, "l16");
84 }
85
86 bool IsIlbc(const CodecInst& codec) {
87 return
88 #ifdef WEBRTC_CODEC_ILBC
89 !STR_CASE_CMP(codec.plname, "ilbc") ||
90 #endif
91 false;
92 }
93
94 bool IsG722(const CodecInst& codec) {
95 return
96 #ifdef WEBRTC_CODEC_G722
97 !STR_CASE_CMP(codec.plname, "g722") ||
98 #endif
99 false;
100 }
101
102 bool CodecSupported(const CodecInst& codec) {
103 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) ||
104 IsIlbc(codec) || IsG722(codec) || IsIsac(codec);
105 }
106
107 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0};
108 } // namespace 66 } // namespace
109 67
110 CodecManager::CodecManager() 68 CodecManager::CodecManager() {
111 : send_codec_inst_(kEmptyCodecInst), encoder_is_opus_(false) {
112 thread_checker_.DetachFromThread(); 69 thread_checker_.DetachFromThread();
113 } 70 }
114 71
115 CodecManager::~CodecManager() = default; 72 CodecManager::~CodecManager() = default;
116 73
117 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { 74 bool CodecManager::RegisterEncoder(const CodecInst& send_codec) {
118 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 75 RTC_DCHECK(thread_checker_.CalledOnValidThread());
119 int codec_id = IsValidSendCodec(send_codec); 76 int codec_id = IsValidSendCodec(send_codec);
120 77
121 // Check for reported errors from function IsValidSendCodec(). 78 // Check for reported errors from function IsValidSendCodec().
122 if (codec_id < 0) { 79 if (codec_id < 0) {
123 return -1; 80 return false;
124 } 81 }
125 82
126 int dummy_id = 0; 83 int dummy_id = 0;
127 switch (RentACodec::RegisterRedPayloadType( 84 switch (RentACodec::RegisterRedPayloadType(
128 &codec_stack_params_.red_payload_types, send_codec)) { 85 &codec_stack_params_.red_payload_types, send_codec)) {
129 case RentACodec::RegistrationResult::kOk: 86 case RentACodec::RegistrationResult::kOk:
130 return 0; 87 return true;
131 case RentACodec::RegistrationResult::kBadFreq: 88 case RentACodec::RegistrationResult::kBadFreq:
132 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, 89 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id,
133 "RegisterSendCodec() failed, invalid frequency for RED" 90 "RegisterSendCodec() failed, invalid frequency for RED"
134 " registration"); 91 " registration");
135 return -1; 92 return false;
136 case RentACodec::RegistrationResult::kSkip: 93 case RentACodec::RegistrationResult::kSkip:
137 break; 94 break;
138 } 95 }
139 switch (RentACodec::RegisterCngPayloadType( 96 switch (RentACodec::RegisterCngPayloadType(
140 &codec_stack_params_.cng_payload_types, send_codec)) { 97 &codec_stack_params_.cng_payload_types, send_codec)) {
141 case RentACodec::RegistrationResult::kOk: 98 case RentACodec::RegistrationResult::kOk:
142 return 0; 99 return true;
143 case RentACodec::RegistrationResult::kBadFreq: 100 case RentACodec::RegistrationResult::kBadFreq:
144 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, 101 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id,
145 "RegisterSendCodec() failed, invalid frequency for CNG" 102 "RegisterSendCodec() failed, invalid frequency for CNG"
146 " registration"); 103 " registration");
147 return -1; 104 return false;
148 case RentACodec::RegistrationResult::kSkip: 105 case RentACodec::RegistrationResult::kSkip:
149 break; 106 break;
150 } 107 }
151 108
152 encoder_is_opus_ = IsOpus(send_codec); 109 if (IsOpus(send_codec)) {
153 if (encoder_is_opus_) {
154 // VAD/DTX not supported. 110 // VAD/DTX not supported.
155 codec_stack_params_.use_cng = false; 111 codec_stack_params_.use_cng = false;
156 } 112 }
157 113
158 // Recreate the encoder if anything except the send bitrate has changed. 114 send_codec_inst_ = rtc::Optional<CodecInst>(send_codec);
159 if (!CurrentEncoder() || send_codec_inst_.pltype != send_codec.pltype || 115 codec_stack_params_.speech_encoder = nullptr; // Caller must recreate it.
160 STR_CASE_CMP(send_codec_inst_.plname, send_codec.plname) != 0 || 116 return true;
161 send_codec_inst_.plfreq != send_codec.plfreq ||
162 send_codec_inst_.pacsize != send_codec.pacsize ||
163 send_codec_inst_.channels != send_codec.channels) {
164 RTC_DCHECK(CodecSupported(send_codec));
165 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
166 if (!enc)
167 return -1;
168 codec_stack_params_.speech_encoder = enc;
169 rent_a_codec_.RentEncoderStack(&codec_stack_params_);
170 RTC_DCHECK(CurrentEncoder());
171 }
172
173 send_codec_inst_ = send_codec;
174 CurrentEncoder()->SetTargetBitrate(send_codec_inst_.rate);
175 return 0;
176 } 117 }
177 118
178 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { 119 CodecInst CodecManager::ForgeCodecInst(
179 // Make up a CodecInst. 120 const AudioEncoder* external_speech_encoder) {
180 send_codec_inst_.channels = external_speech_encoder->NumChannels(); 121 CodecInst ci;
181 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); 122 ci.channels = external_speech_encoder->NumChannels();
182 send_codec_inst_.pacsize = rtc::CheckedDivExact( 123 ci.plfreq = external_speech_encoder->SampleRateHz();
124 ci.pacsize = rtc::CheckedDivExact(
183 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * 125 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() *
184 send_codec_inst_.plfreq), 126 ci.plfreq),
185 100); 127 100);
186 send_codec_inst_.pltype = -1; // Not valid. 128 ci.pltype = -1; // Not valid.
187 send_codec_inst_.rate = -1; // Not valid. 129 ci.rate = -1; // Not valid.
188 static const char kName[] = "external"; 130 static const char kName[] = "external";
189 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); 131 memcpy(ci.plname, kName, sizeof(kName));
190 132 return ci;
191 codec_stack_params_.speech_encoder = external_speech_encoder;
192 rent_a_codec_.RentEncoderStack(&codec_stack_params_);
193 }
194
195 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const {
196 int dummy_id = 0;
197 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
198 "SendCodec()");
199
200 if (!CurrentEncoder()) {
201 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
202 "SendCodec Failed, no codec is registered");
203 return rtc::Optional<CodecInst>();
204 }
205 return rtc::Optional<CodecInst>(send_codec_inst_);
206 } 133 }
207 134
208 bool CodecManager::SetCopyRed(bool enable) { 135 bool CodecManager::SetCopyRed(bool enable) {
209 if (enable && codec_stack_params_.use_codec_fec) { 136 if (enable && codec_stack_params_.use_codec_fec) {
210 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 137 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
211 "Codec internal FEC and RED cannot be co-enabled."); 138 "Codec internal FEC and RED cannot be co-enabled.");
212 return false; 139 return false;
213 } 140 }
214 if (enable && 141 if (enable && send_codec_inst_ &&
215 codec_stack_params_.red_payload_types.count(send_codec_inst_.plfreq) < 142 codec_stack_params_.red_payload_types.count(send_codec_inst_->plfreq) <
216 1) { 143 1) {
217 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 144 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
218 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); 145 "Cannot enable RED at %i Hz.", send_codec_inst_->plfreq);
219 return false; 146 return false;
220 } 147 }
221 if (codec_stack_params_.use_red != enable) { 148 codec_stack_params_.use_red = enable;
222 codec_stack_params_.use_red = enable;
223 if (CurrentEncoder())
224 rent_a_codec_.RentEncoderStack(&codec_stack_params_);
225 }
226 return true; 149 return true;
227 } 150 }
228 151
229 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { 152 bool CodecManager::SetVAD(bool enable, ACMVADMode mode) {
230 // Sanity check of the mode. 153 // Sanity check of the mode.
231 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || 154 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr ||
232 mode == VADVeryAggr); 155 mode == VADVeryAggr);
233 156
234 // Check that the send codec is mono. We don't support VAD/DTX for stereo 157 // Check that the send codec is mono. We don't support VAD/DTX for stereo
235 // sending. 158 // sending.
236 const bool stereo_send = 159 const bool stereo_send =
237 codec_stack_params_.speech_encoder 160 codec_stack_params_.speech_encoder
238 ? (codec_stack_params_.speech_encoder->NumChannels() != 1) 161 ? (codec_stack_params_.speech_encoder->NumChannels() != 1)
239 : false; 162 : false;
240 if (enable && stereo_send) { 163 if (enable && stereo_send) {
241 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, 164 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
242 "VAD/DTX not supported for stereo sending"); 165 "VAD/DTX not supported for stereo sending");
243 codec_stack_params_.use_cng = false; 166 return false;
244 return -1;
245 } 167 }
246 168
247 // If a send codec is registered, set VAD/DTX for the codec. 169 if (CurrentEncoderIsOpus()) {
248 if (IsOpus(send_codec_inst_)) { 170 // VAD/DTX not supported, but don't fail.
249 // VAD/DTX not supported. 171 enable = false;
250 codec_stack_params_.use_cng = false;
251 return 0;
252 } 172 }
253 173
254 if (codec_stack_params_.use_cng != enable || 174 codec_stack_params_.use_cng = enable;
255 codec_stack_params_.vad_mode != mode) { 175 codec_stack_params_.vad_mode = mode;
256 codec_stack_params_.use_cng = enable; 176 return true;
257 codec_stack_params_.vad_mode = mode;
258 if (codec_stack_params_.speech_encoder)
259 rent_a_codec_.RentEncoderStack(&codec_stack_params_);
260 }
261 return 0;
262 } 177 }
263 178
264 void CodecManager::VAD(bool* dtx_enabled, 179 bool CodecManager::SetCodecFEC(bool enable_codec_fec) {
265 bool* vad_enabled,
266 ACMVADMode* mode) const {
267 *dtx_enabled = *vad_enabled = codec_stack_params_.use_cng;
268 *mode = codec_stack_params_.vad_mode;
269 }
270
271 int CodecManager::SetCodecFEC(bool enable_codec_fec) {
272 if (enable_codec_fec && codec_stack_params_.use_red) { 180 if (enable_codec_fec && codec_stack_params_.use_red) {
273 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 181 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
274 "Codec internal FEC and RED cannot be co-enabled."); 182 "Codec internal FEC and RED cannot be co-enabled.");
275 return -1; 183 return false;
276 } 184 }
277 185
278 RTC_CHECK(CurrentEncoder()); 186 codec_stack_params_.use_codec_fec = enable_codec_fec;
279 codec_stack_params_.use_codec_fec = 187 return true;
280 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec;
281 return codec_stack_params_.use_codec_fec == enable_codec_fec ? 0 : -1;
282 } 188 }
283 189
284 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { 190 bool CodecManager::CurrentEncoderIsOpus() const {
285 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; 191 return send_codec_inst_ ? IsOpus(*send_codec_inst_) : false;
286 } 192 }
287 193
288 } // namespace acm2 194 } // namespace acm2
289 } // namespace webrtc 195 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/acm2/codec_manager.h ('k') | webrtc/modules/audio_coding/acm2/codec_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698