OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 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 #include "voice_engine/voe_codec_impl.h" | |
12 | |
13 #include "modules/audio_coding/include/audio_coding_module.h" | |
14 #include "rtc_base/format_macros.h" | |
15 #include "system_wrappers/include/trace.h" | |
16 #include "voice_engine/channel.h" | |
17 #include "voice_engine/include/voe_errors.h" | |
18 #include "voice_engine/voice_engine_impl.h" | |
19 | |
20 namespace webrtc { | |
21 | |
22 VoECodec* VoECodec::GetInterface(VoiceEngine* voiceEngine) { | |
23 if (NULL == voiceEngine) { | |
24 return NULL; | |
25 } | |
26 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); | |
27 s->AddRef(); | |
28 return s; | |
29 } | |
30 | |
31 VoECodecImpl::VoECodecImpl(voe::SharedData* shared) : _shared(shared) { | |
32 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
33 "VoECodecImpl() - ctor"); | |
34 } | |
35 | |
36 VoECodecImpl::~VoECodecImpl() { | |
37 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
38 "~VoECodecImpl() - dtor"); | |
39 } | |
40 | |
41 int VoECodecImpl::NumOfCodecs() { | |
42 // Number of supported codecs in the ACM | |
43 uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); | |
44 return (nSupportedCodecs); | |
45 } | |
46 | |
47 int VoECodecImpl::GetCodec(int index, CodecInst& codec) { | |
48 if (AudioCodingModule::Codec(index, &codec) == -1) { | |
49 _shared->SetLastError(VE_INVALID_LISTNR, kTraceError, | |
50 "GetCodec() invalid index"); | |
51 return -1; | |
52 } | |
53 return 0; | |
54 } | |
55 | |
56 int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec) { | |
57 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
58 "SetSendCodec(channel=%d, codec)", channel); | |
59 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
60 "codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, " | |
61 "channels=%" PRIuS ", rate=%d", | |
62 codec.plname, codec.pacsize, codec.plfreq, codec.pltype, | |
63 codec.channels, codec.rate); | |
64 if (!_shared->statistics().Initialized()) { | |
65 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
66 return -1; | |
67 } | |
68 // External sanity checks performed outside the ACM | |
69 if ((STR_CASE_CMP(codec.plname, "L16") == 0) && (codec.pacsize >= 960)) { | |
70 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, | |
71 "SetSendCodec() invalid L16 packet size"); | |
72 return -1; | |
73 } | |
74 if (!STR_CASE_CMP(codec.plname, "CN") || | |
75 !STR_CASE_CMP(codec.plname, "TELEPHONE-EVENT") || | |
76 !STR_CASE_CMP(codec.plname, "RED")) { | |
77 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, | |
78 "SetSendCodec() invalid codec name"); | |
79 return -1; | |
80 } | |
81 if ((codec.channels != 1) && (codec.channels != 2)) { | |
82 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, | |
83 "SetSendCodec() invalid number of channels"); | |
84 return -1; | |
85 } | |
86 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
87 voe::Channel* channelPtr = ch.channel(); | |
88 if (channelPtr == NULL) { | |
89 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
90 "GetSendCodec() failed to locate channel"); | |
91 return -1; | |
92 } | |
93 if (!AudioCodingModule::IsCodecValid(codec)) { | |
94 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, | |
95 "SetSendCodec() invalid codec"); | |
96 return -1; | |
97 } | |
98 if (channelPtr->SetSendCodec(codec) != 0) { | |
99 _shared->SetLastError(VE_CANNOT_SET_SEND_CODEC, kTraceError, | |
100 "SetSendCodec() failed to set send codec"); | |
101 return -1; | |
102 } | |
103 | |
104 return 0; | |
105 } | |
106 | |
107 int VoECodecImpl::GetSendCodec(int channel, CodecInst& codec) { | |
108 if (!_shared->statistics().Initialized()) { | |
109 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
110 return -1; | |
111 } | |
112 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
113 voe::Channel* channelPtr = ch.channel(); | |
114 if (channelPtr == NULL) { | |
115 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
116 "GetSendCodec() failed to locate channel"); | |
117 return -1; | |
118 } | |
119 if (channelPtr->GetSendCodec(codec) != 0) { | |
120 _shared->SetLastError(VE_CANNOT_GET_SEND_CODEC, kTraceError, | |
121 "GetSendCodec() failed to get send codec"); | |
122 return -1; | |
123 } | |
124 return 0; | |
125 } | |
126 | |
127 int VoECodecImpl::SetBitRate(int channel, int bitrate_bps) { | |
128 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
129 "SetBitRate(bitrate_bps=%d)", bitrate_bps); | |
130 if (!_shared->statistics().Initialized()) { | |
131 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
132 return -1; | |
133 } | |
134 constexpr int64_t kDefaultProbingIntervalMs = 3000; | |
135 _shared->channel_manager().GetChannel(channel).channel()->SetBitRate( | |
136 bitrate_bps, kDefaultProbingIntervalMs); | |
137 return 0; | |
138 } | |
139 | |
140 int VoECodecImpl::GetRecCodec(int channel, CodecInst& codec) { | |
141 if (!_shared->statistics().Initialized()) { | |
142 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
143 return -1; | |
144 } | |
145 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
146 voe::Channel* channelPtr = ch.channel(); | |
147 if (channelPtr == NULL) { | |
148 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
149 "GetRecCodec() failed to locate channel"); | |
150 return -1; | |
151 } | |
152 return channelPtr->GetRecCodec(codec); | |
153 } | |
154 | |
155 int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec) { | |
156 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
157 "SetRecPayloadType(channel=%d, codec)", channel); | |
158 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
159 "codec: plname=%s, plfreq=%d, pltype=%d, channels=%" PRIuS ", " | |
160 "pacsize=%d, rate=%d", | |
161 codec.plname, codec.plfreq, codec.pltype, codec.channels, | |
162 codec.pacsize, codec.rate); | |
163 if (!_shared->statistics().Initialized()) { | |
164 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
165 return -1; | |
166 } | |
167 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
168 voe::Channel* channelPtr = ch.channel(); | |
169 if (channelPtr == NULL) { | |
170 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
171 "GetRecPayloadType() failed to locate channel"); | |
172 return -1; | |
173 } | |
174 return channelPtr->SetRecPayloadType(codec); | |
175 } | |
176 | |
177 int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec) { | |
178 if (!_shared->statistics().Initialized()) { | |
179 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
180 return -1; | |
181 } | |
182 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
183 voe::Channel* channelPtr = ch.channel(); | |
184 if (channelPtr == NULL) { | |
185 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
186 "GetRecPayloadType() failed to locate channel"); | |
187 return -1; | |
188 } | |
189 return channelPtr->GetRecPayloadType(codec); | |
190 } | |
191 | |
192 int VoECodecImpl::SetSendCNPayloadType(int channel, | |
193 int type, | |
194 PayloadFrequencies frequency) { | |
195 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
196 "SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)", | |
197 channel, type, frequency); | |
198 if (!_shared->statistics().Initialized()) { | |
199 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
200 return -1; | |
201 } | |
202 if (type < 96 || type > 127) { | |
203 // Only allow dynamic range: 96 to 127 | |
204 _shared->SetLastError(VE_INVALID_PLTYPE, kTraceError, | |
205 "SetSendCNPayloadType() invalid payload type"); | |
206 return -1; | |
207 } | |
208 if ((frequency != kFreq16000Hz) && (frequency != kFreq32000Hz)) { | |
209 // It is not possible to modify the payload type for CN/8000. | |
210 // We only allow modification of the CN payload type for CN/16000 | |
211 // and CN/32000. | |
212 _shared->SetLastError(VE_INVALID_PLFREQ, kTraceError, | |
213 "SetSendCNPayloadType() invalid payload frequency"); | |
214 return -1; | |
215 } | |
216 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
217 voe::Channel* channelPtr = ch.channel(); | |
218 if (channelPtr == NULL) { | |
219 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
220 "SetSendCNPayloadType() failed to locate channel"); | |
221 return -1; | |
222 } | |
223 return channelPtr->SetSendCNPayloadType(type, frequency); | |
224 } | |
225 | |
226 int VoECodecImpl::SetFECStatus(int channel, bool enable) { | |
227 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
228 "SetCodecFECStatus(channel=%d, enable=%d)", channel, enable); | |
229 if (!_shared->statistics().Initialized()) { | |
230 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
231 return -1; | |
232 } | |
233 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
234 voe::Channel* channelPtr = ch.channel(); | |
235 if (channelPtr == NULL) { | |
236 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
237 "SetCodecFECStatus() failed to locate channel"); | |
238 return -1; | |
239 } | |
240 return channelPtr->SetCodecFECStatus(enable); | |
241 } | |
242 | |
243 int VoECodecImpl::GetFECStatus(int channel, bool& enabled) { | |
244 if (!_shared->statistics().Initialized()) { | |
245 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
246 return -1; | |
247 } | |
248 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
249 voe::Channel* channelPtr = ch.channel(); | |
250 if (channelPtr == NULL) { | |
251 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
252 "GetFECStatus() failed to locate channel"); | |
253 return -1; | |
254 } | |
255 enabled = channelPtr->GetCodecFECStatus(); | |
256 return 0; | |
257 } | |
258 | |
259 int VoECodecImpl::SetVADStatus(int channel, | |
260 bool enable, | |
261 VadModes mode, | |
262 bool disableDTX) { | |
263 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
264 "SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)", | |
265 channel, enable, mode, disableDTX); | |
266 | |
267 if (!_shared->statistics().Initialized()) { | |
268 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
269 return -1; | |
270 } | |
271 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
272 voe::Channel* channelPtr = ch.channel(); | |
273 if (channelPtr == NULL) { | |
274 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
275 "SetVADStatus failed to locate channel"); | |
276 return -1; | |
277 } | |
278 | |
279 ACMVADMode vadMode(VADNormal); | |
280 switch (mode) { | |
281 case kVadConventional: | |
282 vadMode = VADNormal; | |
283 break; | |
284 case kVadAggressiveLow: | |
285 vadMode = VADLowBitrate; | |
286 break; | |
287 case kVadAggressiveMid: | |
288 vadMode = VADAggr; | |
289 break; | |
290 case kVadAggressiveHigh: | |
291 vadMode = VADVeryAggr; | |
292 break; | |
293 } | |
294 return channelPtr->SetVADStatus(enable, vadMode, disableDTX); | |
295 } | |
296 | |
297 int VoECodecImpl::GetVADStatus(int channel, | |
298 bool& enabled, | |
299 VadModes& mode, | |
300 bool& disabledDTX) { | |
301 if (!_shared->statistics().Initialized()) { | |
302 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
303 return -1; | |
304 } | |
305 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
306 voe::Channel* channelPtr = ch.channel(); | |
307 if (channelPtr == NULL) { | |
308 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
309 "GetVADStatus failed to locate channel"); | |
310 return -1; | |
311 } | |
312 | |
313 ACMVADMode vadMode; | |
314 int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX); | |
315 | |
316 if (ret != 0) { | |
317 _shared->SetLastError(VE_INVALID_OPERATION, kTraceError, | |
318 "GetVADStatus failed to get VAD mode"); | |
319 return -1; | |
320 } | |
321 switch (vadMode) { | |
322 case VADNormal: | |
323 mode = kVadConventional; | |
324 break; | |
325 case VADLowBitrate: | |
326 mode = kVadAggressiveLow; | |
327 break; | |
328 case VADAggr: | |
329 mode = kVadAggressiveMid; | |
330 break; | |
331 case VADVeryAggr: | |
332 mode = kVadAggressiveHigh; | |
333 break; | |
334 } | |
335 | |
336 return 0; | |
337 } | |
338 | |
339 int VoECodecImpl::SetOpusMaxPlaybackRate(int channel, int frequency_hz) { | |
340 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
341 "SetOpusMaxPlaybackRate(channel=%d, frequency_hz=%d)", channel, | |
342 frequency_hz); | |
343 if (!_shared->statistics().Initialized()) { | |
344 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
345 return -1; | |
346 } | |
347 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
348 voe::Channel* channelPtr = ch.channel(); | |
349 if (channelPtr == NULL) { | |
350 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
351 "SetOpusMaxPlaybackRate failed to locate channel"); | |
352 return -1; | |
353 } | |
354 return channelPtr->SetOpusMaxPlaybackRate(frequency_hz); | |
355 } | |
356 | |
357 int VoECodecImpl::SetOpusDtx(int channel, bool enable_dtx) { | |
358 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
359 "SetOpusDtx(channel=%d, enable_dtx=%d)", channel, enable_dtx); | |
360 if (!_shared->statistics().Initialized()) { | |
361 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
362 return -1; | |
363 } | |
364 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
365 voe::Channel* channelPtr = ch.channel(); | |
366 if (channelPtr == NULL) { | |
367 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
368 "SetOpusDtx failed to locate channel"); | |
369 return -1; | |
370 } | |
371 return channelPtr->SetOpusDtx(enable_dtx); | |
372 } | |
373 | |
374 int VoECodecImpl::GetOpusDtxStatus(int channel, bool* enabled) { | |
375 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), | |
376 "GetOpusDtx(channel=%d)", channel); | |
377 if (!_shared->statistics().Initialized()) { | |
378 _shared->SetLastError(VE_NOT_INITED, kTraceError); | |
379 return -1; | |
380 } | |
381 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); | |
382 voe::Channel* channelPtr = ch.channel(); | |
383 if (channelPtr == NULL) { | |
384 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | |
385 "GetOpusDtx failed to locate channel"); | |
386 return -1; | |
387 } | |
388 return channelPtr->GetOpusDtx(enabled); | |
389 } | |
390 | |
391 } // namespace webrtc | |
OLD | NEW |