blob: 19891bc39fae52399f23e224db25342fd6642f37 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:231/*
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
pbos@webrtc.org471ae722013-05-21 13:52:3211#include "webrtc/voice_engine/voe_codec_impl.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:2312
Peter Kasting80590d92016-01-13 00:26:3513#include "webrtc/base/format_macros.h"
kjellander0c1546c2015-11-26 12:44:5414#include "webrtc/modules/audio_coding/include/audio_coding_module.h"
Henrik Kjellander78f65d02015-10-28 17:17:4015#include "webrtc/system_wrappers/include/trace.h"
pbos@webrtc.org471ae722013-05-21 13:52:3216#include "webrtc/voice_engine/channel.h"
17#include "webrtc/voice_engine/include/voe_errors.h"
18#include "webrtc/voice_engine/voice_engine_impl.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:2319
Jelena Marusic0705a022015-05-04 12:15:3220namespace webrtc {
andrew@webrtc.orgb015cbe2012-10-22 18:19:2321
Jelena Marusic0705a022015-05-04 12:15:3222VoECodec* VoECodec::GetInterface(VoiceEngine* voiceEngine) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:2323#ifndef WEBRTC_VOICE_ENGINE_CODEC_API
Jelena Marusic0705a022015-05-04 12:15:3224 return NULL;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2325#else
Jelena Marusic0705a022015-05-04 12:15:3226 if (NULL == voiceEngine) {
27 return NULL;
28 }
29 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
30 s->AddRef();
31 return s;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2332#endif
33}
34
35#ifdef WEBRTC_VOICE_ENGINE_CODEC_API
36
Jelena Marusic0705a022015-05-04 12:15:3237VoECodecImpl::VoECodecImpl(voe::SharedData* shared) : _shared(shared) {
38 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
39 "VoECodecImpl() - ctor");
andrew@webrtc.orgb015cbe2012-10-22 18:19:2340}
41
Jelena Marusic0705a022015-05-04 12:15:3242VoECodecImpl::~VoECodecImpl() {
43 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
44 "~VoECodecImpl() - dtor");
andrew@webrtc.orgb015cbe2012-10-22 18:19:2345}
46
Jelena Marusic0705a022015-05-04 12:15:3247int VoECodecImpl::NumOfCodecs() {
Jelena Marusic0705a022015-05-04 12:15:3248 // Number of supported codecs in the ACM
49 uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
Jelena Marusic0705a022015-05-04 12:15:3250 return (nSupportedCodecs);
andrew@webrtc.orgb015cbe2012-10-22 18:19:2351}
52
Jelena Marusic0705a022015-05-04 12:15:3253int VoECodecImpl::GetCodec(int index, CodecInst& codec) {
kwiberga67ca872015-11-19 19:08:2954 if (AudioCodingModule::Codec(index, &codec) == -1) {
Jelena Marusic0705a022015-05-04 12:15:3255 _shared->SetLastError(VE_INVALID_LISTNR, kTraceError,
56 "GetCodec() invalid index");
57 return -1;
58 }
Jelena Marusic0705a022015-05-04 12:15:3259 return 0;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2360}
61
Jelena Marusic0705a022015-05-04 12:15:3262int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec) {
Jelena Marusic0705a022015-05-04 12:15:3263 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
64 "SetSendCodec(channel=%d, codec)", channel);
65 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
66 "codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
Peter Kasting80590d92016-01-13 00:26:3567 "channels=%" PRIuS ", rate=%d",
Jelena Marusic0705a022015-05-04 12:15:3268 codec.plname, codec.pacsize, codec.plfreq, codec.pltype,
69 codec.channels, codec.rate);
70 if (!_shared->statistics().Initialized()) {
71 _shared->SetLastError(VE_NOT_INITED, kTraceError);
72 return -1;
73 }
74 // External sanity checks performed outside the ACM
kwiberga67ca872015-11-19 19:08:2975 if ((STR_CASE_CMP(codec.plname, "L16") == 0) && (codec.pacsize >= 960)) {
Jelena Marusic0705a022015-05-04 12:15:3276 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
77 "SetSendCodec() invalid L16 packet size");
78 return -1;
79 }
kwiberga67ca872015-11-19 19:08:2980 if (!STR_CASE_CMP(codec.plname, "CN") ||
81 !STR_CASE_CMP(codec.plname, "TELEPHONE-EVENT") ||
82 !STR_CASE_CMP(codec.plname, "RED")) {
Jelena Marusic0705a022015-05-04 12:15:3283 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
84 "SetSendCodec() invalid codec name");
85 return -1;
86 }
kwiberga67ca872015-11-19 19:08:2987 if ((codec.channels != 1) && (codec.channels != 2)) {
Jelena Marusic0705a022015-05-04 12:15:3288 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
89 "SetSendCodec() invalid number of channels");
90 return -1;
91 }
92 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
93 voe::Channel* channelPtr = ch.channel();
94 if (channelPtr == NULL) {
95 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
96 "GetSendCodec() failed to locate channel");
97 return -1;
98 }
kwiberga67ca872015-11-19 19:08:2999 if (!AudioCodingModule::IsCodecValid(codec)) {
Jelena Marusic0705a022015-05-04 12:15:32100 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
101 "SetSendCodec() invalid codec");
102 return -1;
103 }
kwiberga67ca872015-11-19 19:08:29104 if (channelPtr->SetSendCodec(codec) != 0) {
Jelena Marusic0705a022015-05-04 12:15:32105 _shared->SetLastError(VE_CANNOT_SET_SEND_CODEC, kTraceError,
106 "SetSendCodec() failed to set send codec");
107 return -1;
108 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23109
Jelena Marusic0705a022015-05-04 12:15:32110 return 0;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23111}
112
Jelena Marusic0705a022015-05-04 12:15:32113int VoECodecImpl::GetSendCodec(int channel, CodecInst& codec) {
Jelena Marusic0705a022015-05-04 12:15:32114 if (!_shared->statistics().Initialized()) {
115 _shared->SetLastError(VE_NOT_INITED, kTraceError);
116 return -1;
117 }
118 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
119 voe::Channel* channelPtr = ch.channel();
120 if (channelPtr == NULL) {
121 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
122 "GetSendCodec() failed to locate channel");
123 return -1;
124 }
kwiberga67ca872015-11-19 19:08:29125 if (channelPtr->GetSendCodec(codec) != 0) {
Jelena Marusic0705a022015-05-04 12:15:32126 _shared->SetLastError(VE_CANNOT_GET_SEND_CODEC, kTraceError,
127 "GetSendCodec() failed to get send codec");
128 return -1;
129 }
Jelena Marusic0705a022015-05-04 12:15:32130 return 0;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23131}
132
Ivo Creusenf0b18c62015-04-29 14:03:33133int VoECodecImpl::SetBitRate(int channel, int bitrate_bps) {
134 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
135 "SetBitRate(bitrate_bps=%d)", bitrate_bps);
136 if (!_shared->statistics().Initialized()) {
137 _shared->SetLastError(VE_NOT_INITED, kTraceError);
138 return -1;
139 }
140 _shared->channel_manager().GetChannel(channel).channel()->SetBitRate(
141 bitrate_bps);
142 return 0;
143}
144
Jelena Marusic0705a022015-05-04 12:15:32145int VoECodecImpl::GetRecCodec(int channel, CodecInst& codec) {
Jelena Marusic0705a022015-05-04 12:15:32146 if (!_shared->statistics().Initialized()) {
147 _shared->SetLastError(VE_NOT_INITED, kTraceError);
148 return -1;
149 }
150 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
151 voe::Channel* channelPtr = ch.channel();
152 if (channelPtr == NULL) {
153 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
154 "GetRecCodec() failed to locate channel");
155 return -1;
156 }
kwiberga67ca872015-11-19 19:08:29157 return channelPtr->GetRecCodec(codec);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23158}
159
Jelena Marusic0705a022015-05-04 12:15:32160int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec) {
161 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
162 "SetRecPayloadType(channel=%d, codec)", channel);
163 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
Peter Kasting80590d92016-01-13 00:26:35164 "codec: plname=%s, plfreq=%d, pltype=%d, channels=%" PRIuS ", "
Jelena Marusic0705a022015-05-04 12:15:32165 "pacsize=%d, rate=%d",
166 codec.plname, codec.plfreq, codec.pltype, codec.channels,
167 codec.pacsize, codec.rate);
168 if (!_shared->statistics().Initialized()) {
169 _shared->SetLastError(VE_NOT_INITED, kTraceError);
170 return -1;
171 }
172 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
173 voe::Channel* channelPtr = ch.channel();
174 if (channelPtr == NULL) {
175 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
176 "GetRecPayloadType() failed to locate channel");
177 return -1;
178 }
179 return channelPtr->SetRecPayloadType(codec);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23180}
181
Jelena Marusic0705a022015-05-04 12:15:32182int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec) {
Jelena Marusic0705a022015-05-04 12:15:32183 if (!_shared->statistics().Initialized()) {
184 _shared->SetLastError(VE_NOT_INITED, kTraceError);
185 return -1;
186 }
187 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
188 voe::Channel* channelPtr = ch.channel();
189 if (channelPtr == NULL) {
190 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
191 "GetRecPayloadType() failed to locate channel");
192 return -1;
193 }
194 return channelPtr->GetRecPayloadType(codec);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23195}
196
Jelena Marusic0705a022015-05-04 12:15:32197int VoECodecImpl::SetSendCNPayloadType(int channel,
198 int type,
199 PayloadFrequencies frequency) {
200 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
201 "SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)",
202 channel, type, frequency);
203 if (!_shared->statistics().Initialized()) {
204 _shared->SetLastError(VE_NOT_INITED, kTraceError);
205 return -1;
206 }
207 if (type < 96 || type > 127) {
208 // Only allow dynamic range: 96 to 127
209 _shared->SetLastError(VE_INVALID_PLTYPE, kTraceError,
210 "SetSendCNPayloadType() invalid payload type");
211 return -1;
212 }
213 if ((frequency != kFreq16000Hz) && (frequency != kFreq32000Hz)) {
214 // It is not possible to modify the payload type for CN/8000.
215 // We only allow modification of the CN payload type for CN/16000
216 // and CN/32000.
217 _shared->SetLastError(VE_INVALID_PLFREQ, kTraceError,
218 "SetSendCNPayloadType() invalid payload frequency");
219 return -1;
220 }
221 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
222 voe::Channel* channelPtr = ch.channel();
223 if (channelPtr == NULL) {
224 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
225 "SetSendCNPayloadType() failed to locate channel");
226 return -1;
227 }
228 return channelPtr->SetSendCNPayloadType(type, frequency);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23229}
230
minyue@webrtc.orgdd671de2014-05-28 09:52:06231int VoECodecImpl::SetFECStatus(int channel, bool enable) {
232 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
233 "SetCodecFECStatus(channel=%d, enable=%d)", channel, enable);
234 if (!_shared->statistics().Initialized()) {
235 _shared->SetLastError(VE_NOT_INITED, kTraceError);
236 return -1;
237 }
238 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
239 voe::Channel* channelPtr = ch.channel();
240 if (channelPtr == NULL) {
241 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
242 "SetCodecFECStatus() failed to locate channel");
243 return -1;
244 }
245 return channelPtr->SetCodecFECStatus(enable);
246}
247
248int VoECodecImpl::GetFECStatus(int channel, bool& enabled) {
minyue@webrtc.orgdd671de2014-05-28 09:52:06249 if (!_shared->statistics().Initialized()) {
250 _shared->SetLastError(VE_NOT_INITED, kTraceError);
251 return -1;
252 }
253 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
254 voe::Channel* channelPtr = ch.channel();
255 if (channelPtr == NULL) {
256 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
257 "GetFECStatus() failed to locate channel");
258 return -1;
259 }
260 enabled = channelPtr->GetCodecFECStatus();
261 return 0;
262}
263
Jelena Marusic0705a022015-05-04 12:15:32264int VoECodecImpl::SetVADStatus(int channel,
265 bool enable,
266 VadModes mode,
267 bool disableDTX) {
268 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
269 "SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)",
270 channel, enable, mode, disableDTX);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23271
Jelena Marusic0705a022015-05-04 12:15:32272 if (!_shared->statistics().Initialized()) {
273 _shared->SetLastError(VE_NOT_INITED, kTraceError);
274 return -1;
275 }
276 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
277 voe::Channel* channelPtr = ch.channel();
278 if (channelPtr == NULL) {
279 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
280 "SetVADStatus failed to locate channel");
281 return -1;
282 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23283
Jelena Marusic0705a022015-05-04 12:15:32284 ACMVADMode vadMode(VADNormal);
285 switch (mode) {
286 case kVadConventional:
287 vadMode = VADNormal;
288 break;
289 case kVadAggressiveLow:
290 vadMode = VADLowBitrate;
291 break;
292 case kVadAggressiveMid:
293 vadMode = VADAggr;
294 break;
295 case kVadAggressiveHigh:
296 vadMode = VADVeryAggr;
297 break;
298 }
299 return channelPtr->SetVADStatus(enable, vadMode, disableDTX);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23300}
301
Jelena Marusic0705a022015-05-04 12:15:32302int VoECodecImpl::GetVADStatus(int channel,
303 bool& enabled,
304 VadModes& mode,
305 bool& disabledDTX) {
Jelena Marusic0705a022015-05-04 12:15:32306 if (!_shared->statistics().Initialized()) {
307 _shared->SetLastError(VE_NOT_INITED, kTraceError);
308 return -1;
309 }
310 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
311 voe::Channel* channelPtr = ch.channel();
312 if (channelPtr == NULL) {
313 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
314 "GetVADStatus failed to locate channel");
315 return -1;
316 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23317
Jelena Marusic0705a022015-05-04 12:15:32318 ACMVADMode vadMode;
319 int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23320
Jelena Marusic0705a022015-05-04 12:15:32321 if (ret != 0) {
322 _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
323 "GetVADStatus failed to get VAD mode");
324 return -1;
325 }
326 switch (vadMode) {
327 case VADNormal:
328 mode = kVadConventional;
329 break;
330 case VADLowBitrate:
331 mode = kVadAggressiveLow;
332 break;
333 case VADAggr:
334 mode = kVadAggressiveMid;
335 break;
336 case VADVeryAggr:
337 mode = kVadAggressiveHigh;
338 break;
339 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23340
Jelena Marusic0705a022015-05-04 12:15:32341 return 0;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23342}
343
minyue@webrtc.orgb0aac712014-09-03 12:28:06344int VoECodecImpl::SetOpusMaxPlaybackRate(int channel, int frequency_hz) {
minyue@webrtc.org1bfd5402014-08-12 08:13:33345 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
minyue@webrtc.orgb0aac712014-09-03 12:28:06346 "SetOpusMaxPlaybackRate(channel=%d, frequency_hz=%d)", channel,
347 frequency_hz);
minyue@webrtc.org1bfd5402014-08-12 08:13:33348 if (!_shared->statistics().Initialized()) {
349 _shared->SetLastError(VE_NOT_INITED, kTraceError);
350 return -1;
351 }
352 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
353 voe::Channel* channelPtr = ch.channel();
354 if (channelPtr == NULL) {
355 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
minyue@webrtc.orgb0aac712014-09-03 12:28:06356 "SetOpusMaxPlaybackRate failed to locate channel");
minyue@webrtc.org1bfd5402014-08-12 08:13:33357 return -1;
358 }
minyue@webrtc.orgb0aac712014-09-03 12:28:06359 return channelPtr->SetOpusMaxPlaybackRate(frequency_hz);
minyue@webrtc.org1bfd5402014-08-12 08:13:33360}
361
minyue@webrtc.org04877592015-03-13 09:38:07362int VoECodecImpl::SetOpusDtx(int channel, bool enable_dtx) {
363 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
364 "SetOpusDtx(channel=%d, enable_dtx=%d)", channel, enable_dtx);
365 if (!_shared->statistics().Initialized()) {
366 _shared->SetLastError(VE_NOT_INITED, kTraceError);
367 return -1;
368 }
369 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
370 voe::Channel* channelPtr = ch.channel();
371 if (channelPtr == NULL) {
372 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
373 "SetOpusDtx failed to locate channel");
374 return -1;
375 }
376 return channelPtr->SetOpusDtx(enable_dtx);
377}
378
andrew@webrtc.orgb015cbe2012-10-22 18:19:23379#endif // WEBRTC_VOICE_ENGINE_CODEC_API
380
pbos@webrtc.org3b89e102013-07-03 15:12:26381} // namespace webrtc