blob: 4aa0556ea3f443f35fd8aa0dd55a7eebb8ea3cfe [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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.org956aa7e2013-05-21 13:52:32 +000011#include "webrtc/voice_engine/voe_codec_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org956aa7e2013-05-21 13:52:32 +000013#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
14#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
15#include "webrtc/system_wrappers/interface/trace.h"
16#include "webrtc/voice_engine/channel.h"
17#include "webrtc/voice_engine/include/voe_errors.h"
18#include "webrtc/voice_engine/voice_engine_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000019
20namespace webrtc
21{
22
23VoECodec* VoECodec::GetInterface(VoiceEngine* voiceEngine)
24{
25#ifndef WEBRTC_VOICE_ENGINE_CODEC_API
26 return NULL;
27#else
28 if (NULL == voiceEngine)
29 {
30 return NULL;
31 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000032 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000033 s->AddRef();
34 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000035#endif
36}
37
38#ifdef WEBRTC_VOICE_ENGINE_CODEC_API
39
tommi@webrtc.org851becd2012-04-04 14:57:19 +000040VoECodecImpl::VoECodecImpl(voe::SharedData* shared) : _shared(shared)
niklase@google.com470e71d2011-07-07 08:21:25 +000041{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000042 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000043 "VoECodecImpl() - ctor");
44}
45
46VoECodecImpl::~VoECodecImpl()
47{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000048 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000049 "~VoECodecImpl() - dtor");
50}
51
niklase@google.com470e71d2011-07-07 08:21:25 +000052int VoECodecImpl::NumOfCodecs()
53{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000054 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000055 "NumOfCodecs()");
56
57 // Number of supported codecs in the ACM
pbos@webrtc.org6141e132013-04-09 10:09:10 +000058 uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
niklase@google.com470e71d2011-07-07 08:21:25 +000059
tommi@webrtc.org851becd2012-04-04 14:57:19 +000060 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
61 VoEId(_shared->instance_id(), -1),
62 "NumOfCodecs() => %u", nSupportedCodecs);
niklase@google.com470e71d2011-07-07 08:21:25 +000063 return (nSupportedCodecs);
64}
65
66int VoECodecImpl::GetCodec(int index, CodecInst& codec)
67{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000068 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000069 "GetCodec(index=%d, codec=?)", index);
70 CodecInst acmCodec;
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +000071 if (AudioCodingModule::Codec(index, &acmCodec)
niklase@google.com470e71d2011-07-07 08:21:25 +000072 == -1)
73 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000074 _shared->SetLastError(VE_INVALID_LISTNR, kTraceError,
75 "GetCodec() invalid index");
niklase@google.com470e71d2011-07-07 08:21:25 +000076 return -1;
77 }
78 ACMToExternalCodecRepresentation(codec, acmCodec);
tommi@webrtc.org851becd2012-04-04 14:57:19 +000079 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
80 VoEId(_shared->instance_id(), -1),
81 "GetCodec() => plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
82 "channels=%d, rate=%d", codec.plname, codec.pacsize,
83 codec.plfreq, codec.pltype, codec.channels, codec.rate);
niklase@google.com470e71d2011-07-07 08:21:25 +000084 return 0;
85}
86
87int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec)
88{
89 CodecInst copyCodec;
90 ExternalToACMCodecRepresentation(copyCodec, codec);
91
tommi@webrtc.org851becd2012-04-04 14:57:19 +000092 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000093 "SetSendCodec(channel=%d, codec)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +000094 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000095 "codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
96 "channels=%d, rate=%d", codec.plname, codec.pacsize,
97 codec.plfreq, codec.pltype, codec.channels, codec.rate);
tommi@webrtc.org851becd2012-04-04 14:57:19 +000098 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +000099 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000100 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 return -1;
102 }
103 // External sanity checks performed outside the ACM
104 if ((STR_CASE_CMP(copyCodec.plname, "L16") == 0) &&
105 (copyCodec.pacsize >= 960))
106 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000107 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
108 "SetSendCodec() invalid L16 packet size");
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 return -1;
110 }
111 if (!STR_CASE_CMP(copyCodec.plname, "CN")
112 || !STR_CASE_CMP(copyCodec.plname, "TELEPHONE-EVENT")
113 || !STR_CASE_CMP(copyCodec.plname, "RED"))
114 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000115 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
116 "SetSendCodec() invalid codec name");
niklase@google.com470e71d2011-07-07 08:21:25 +0000117 return -1;
118 }
niklas.enbom@webrtc.orge33a1022011-11-16 10:33:53 +0000119 if ((copyCodec.channels != 1) && (copyCodec.channels != 2))
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000121 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
122 "SetSendCodec() invalid number of channels");
niklase@google.com470e71d2011-07-07 08:21:25 +0000123 return -1;
124 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000125 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
126 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000127 if (channelPtr == NULL)
128 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000129 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
130 "GetSendCodec() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 return -1;
132 }
133 if (!AudioCodingModule::IsCodecValid(
134 (CodecInst&) copyCodec))
135 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000136 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
137 "SetSendCodec() invalid codec");
niklase@google.com470e71d2011-07-07 08:21:25 +0000138 return -1;
139 }
140 if (channelPtr->SetSendCodec(copyCodec) != 0)
141 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000142 _shared->SetLastError(VE_CANNOT_SET_SEND_CODEC, kTraceError,
143 "SetSendCodec() failed to set send codec");
niklase@google.com470e71d2011-07-07 08:21:25 +0000144 return -1;
145 }
146
niklase@google.com470e71d2011-07-07 08:21:25 +0000147 return 0;
148}
149
150int VoECodecImpl::GetSendCodec(int channel, CodecInst& codec)
151{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000152 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000153 "GetSendCodec(channel=%d, codec=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000154 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000156 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000157 return -1;
158 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000159 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
160 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000161 if (channelPtr == NULL)
162 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000163 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
164 "GetSendCodec() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 return -1;
166 }
167 CodecInst acmCodec;
168 if (channelPtr->GetSendCodec(acmCodec) != 0)
169 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000170 _shared->SetLastError(VE_CANNOT_GET_SEND_CODEC, kTraceError,
171 "GetSendCodec() failed to get send codec");
niklase@google.com470e71d2011-07-07 08:21:25 +0000172 return -1;
173 }
174 ACMToExternalCodecRepresentation(codec, acmCodec);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000175 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
176 VoEId(_shared->instance_id(), -1),
177 "GetSendCodec() => plname=%s, pacsize=%d, plfreq=%d, "
178 "channels=%d, rate=%d", codec.plname, codec.pacsize,
179 codec.plfreq, codec.channels, codec.rate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000180 return 0;
181}
182
183int VoECodecImpl::GetRecCodec(int channel, CodecInst& codec)
184{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000185 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 "GetRecCodec(channel=%d, codec=?)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000187 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000189 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 return -1;
191 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000192 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
193 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000194 if (channelPtr == NULL)
195 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000196 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
197 "GetRecCodec() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000198 return -1;
199 }
200 CodecInst acmCodec;
201 if (channelPtr->GetRecCodec(acmCodec) != 0)
202 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000203 _shared->SetLastError(VE_CANNOT_GET_REC_CODEC, kTraceError,
204 "GetRecCodec() failed to get received codec");
niklase@google.com470e71d2011-07-07 08:21:25 +0000205 return -1;
206 }
207 ACMToExternalCodecRepresentation(codec, acmCodec);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000208 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
209 VoEId(_shared->instance_id(), -1),
210 "GetRecCodec() => plname=%s, pacsize=%d, plfreq=%d, "
211 "channels=%d, rate=%d", codec.plname, codec.pacsize,
212 codec.plfreq, codec.channels, codec.rate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000213 return 0;
214}
215
niklase@google.com470e71d2011-07-07 08:21:25 +0000216int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec)
217{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000218 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000219 "SetRecPayloadType(channel=%d, codec)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000220 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000221 "codec: plname=%s, plfreq=%d, pltype=%d, channels=%u, "
222 "pacsize=%d, rate=%d", codec.plname, codec.plfreq, codec.pltype,
223 codec.channels, codec.pacsize, codec.rate);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000224 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000225 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000226 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000227 return -1;
228 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000229 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
230 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000231 if (channelPtr == NULL)
232 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000233 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
234 "GetRecPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000235 return -1;
236 }
237 return channelPtr->SetRecPayloadType(codec);
238}
239
240int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec)
241{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000242 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000243 "GetRecPayloadType(channel=%d, codec)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000244 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000245 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000246 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000247 return -1;
248 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000249 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
250 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000251 if (channelPtr == NULL)
252 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000253 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
254 "GetRecPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000255 return -1;
256 }
257 return channelPtr->GetRecPayloadType(codec);
258}
259
260int VoECodecImpl::SetSendCNPayloadType(int channel, int type,
261 PayloadFrequencies frequency)
262{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000263 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000264 "SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)",
265 channel, type, frequency);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000266 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000267 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000268 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000269 return -1;
270 }
271 if (type < 96 || type > 127)
272 {
273 // Only allow dynamic range: 96 to 127
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000274 _shared->SetLastError(VE_INVALID_PLTYPE, kTraceError,
275 "SetSendCNPayloadType() invalid payload type");
niklase@google.com470e71d2011-07-07 08:21:25 +0000276 return -1;
277 }
278 if ((frequency != kFreq16000Hz) && (frequency != kFreq32000Hz))
279 {
280 // It is not possible to modify the payload type for CN/8000.
281 // We only allow modification of the CN payload type for CN/16000
282 // and CN/32000.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000283 _shared->SetLastError(VE_INVALID_PLFREQ, kTraceError,
284 "SetSendCNPayloadType() invalid payload frequency");
niklase@google.com470e71d2011-07-07 08:21:25 +0000285 return -1;
286 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000287 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
288 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000289 if (channelPtr == NULL)
290 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000291 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
292 "SetSendCNPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000293 return -1;
294 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000295 return channelPtr->SetSendCNPayloadType(type, frequency);
296}
297
minyue@webrtc.orgc1a40a72014-05-28 09:52:06 +0000298int VoECodecImpl::SetFECStatus(int channel, bool enable) {
299 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
300 "SetCodecFECStatus(channel=%d, enable=%d)", channel, enable);
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 "SetCodecFECStatus() failed to locate channel");
310 return -1;
311 }
312 return channelPtr->SetCodecFECStatus(enable);
313}
314
315int VoECodecImpl::GetFECStatus(int channel, bool& enabled) {
316 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
317 "GetCodecFECStatus(channel=%d)", channel);
318 if (!_shared->statistics().Initialized()) {
319 _shared->SetLastError(VE_NOT_INITED, kTraceError);
320 return -1;
321 }
322 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
323 voe::Channel* channelPtr = ch.channel();
324 if (channelPtr == NULL) {
325 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
326 "GetFECStatus() failed to locate channel");
327 return -1;
328 }
329 enabled = channelPtr->GetCodecFECStatus();
330 return 0;
331}
332
niklase@google.com470e71d2011-07-07 08:21:25 +0000333int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode,
334 bool disableDTX)
335{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000336 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 "SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)",
338 channel, enable, mode, disableDTX);
339
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000340 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000341 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000342 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 return -1;
344 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000345 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
346 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 if (channelPtr == NULL)
348 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000349 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
350 "SetVADStatus failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 return -1;
352 }
353
354 ACMVADMode vadMode(VADNormal);
355 switch (mode)
356 {
357 case kVadConventional:
358 vadMode = VADNormal;
359 break;
360 case kVadAggressiveLow:
361 vadMode = VADLowBitrate;
362 break;
363 case kVadAggressiveMid:
364 vadMode = VADAggr;
365 break;
366 case kVadAggressiveHigh:
367 vadMode = VADVeryAggr;
368 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000369 }
370 return channelPtr->SetVADStatus(enable, vadMode, disableDTX);
371}
372
373int VoECodecImpl::GetVADStatus(int channel, bool& enabled, VadModes& mode,
374 bool& disabledDTX)
375{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000376 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000377 "GetVADStatus(channel=%i)", channel);
378
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000379 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000381 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 return -1;
383 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000384 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
385 voe::Channel* channelPtr = ch.channel();
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 if (channelPtr == NULL)
387 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000388 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
389 "GetVADStatus failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000390 return -1;
391 }
392
393 ACMVADMode vadMode;
394 int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX);
395
396 if (ret != 0)
397 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000398 _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
399 "GetVADStatus failed to get VAD mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000400 return -1;
401 }
402 switch (vadMode)
403 {
404 case VADNormal:
405 mode = kVadConventional;
406 break;
407 case VADLowBitrate:
408 mode = kVadAggressiveLow;
409 break;
410 case VADAggr:
411 mode = kVadAggressiveMid;
412 break;
413 case VADVeryAggr:
414 mode = kVadAggressiveHigh;
415 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 }
417
418 return 0;
419}
420
421void VoECodecImpl::ACMToExternalCodecRepresentation(CodecInst& toInst,
422 const CodecInst& fromInst)
423{
424 toInst = fromInst;
425 if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
426 {
427 if (fromInst.plfreq == 12000)
428 {
429 if (fromInst.pacsize == 320)
430 {
431 toInst.pacsize = 240;
432 }
433 else if (fromInst.pacsize == 640)
434 {
435 toInst.pacsize = 480;
436 }
437 else if (fromInst.pacsize == 960)
438 {
439 toInst.pacsize = 720;
440 }
441 }
442 else if (fromInst.plfreq == 24000)
443 {
444 if (fromInst.pacsize == 640)
445 {
446 toInst.pacsize = 480;
447 }
448 else if (fromInst.pacsize == 1280)
449 {
450 toInst.pacsize = 960;
451 }
452 else if (fromInst.pacsize == 1920)
453 {
454 toInst.pacsize = 1440;
455 }
456 }
457 }
458}
459
460void VoECodecImpl::ExternalToACMCodecRepresentation(CodecInst& toInst,
461 const CodecInst& fromInst)
462{
463 toInst = fromInst;
464 if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
465 {
466 if (fromInst.plfreq == 12000)
467 {
468 if (fromInst.pacsize == 240)
469 {
470 toInst.pacsize = 320;
471 }
472 else if (fromInst.pacsize == 480)
473 {
474 toInst.pacsize = 640;
475 }
476 else if (fromInst.pacsize == 720)
477 {
478 toInst.pacsize = 960;
479 }
480 }
481 else if (fromInst.plfreq == 24000)
482 {
483 if (fromInst.pacsize == 480)
484 {
485 toInst.pacsize = 640;
486 }
487 else if (fromInst.pacsize == 960)
488 {
489 toInst.pacsize = 1280;
490 }
491 else if (fromInst.pacsize == 1440)
492 {
493 toInst.pacsize = 1920;
494 }
495 }
496 }
497}
498
turaj@webrtc.org42259e72012-12-11 02:15:12 +0000499int VoECodecImpl::SetSecondarySendCodec(int channel, const CodecInst& codec,
500 int red_payload_type) {
501 CodecInst copy_codec;
502 ExternalToACMCodecRepresentation(copy_codec, codec);
503
504 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
505 "SetSecondarySendCodec(channel=%d, codec)", channel);
506 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
507 "codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
508 "channels=%d, rate=%d", codec.plname, codec.pacsize,
509 codec.plfreq, codec.pltype, codec.channels, codec.rate);
510 if (!_shared->statistics().Initialized()) {
511 _shared->SetLastError(VE_NOT_INITED, kTraceError);
512 return -1;
513 }
514
515 // External sanity checks performed outside the ACM
516 if ((STR_CASE_CMP(copy_codec.plname, "L16") == 0) &&
517 (copy_codec.pacsize >= 960)) {
518 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
519 "SetSecondarySendCodec() invalid L16 packet size");
520 return -1;
521 }
522
523 // None of the following codecs can be registered as the secondary encoder.
524 if (!STR_CASE_CMP(copy_codec.plname, "CN") ||
525 !STR_CASE_CMP(copy_codec.plname, "TELEPHONE-EVENT") ||
526 !STR_CASE_CMP(copy_codec.plname, "RED")) {
527 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
528 "SetSecondarySendCodec() invalid codec name");
529 return -1;
530 }
531
532 // Only mono and stereo are supported.
533 if ((copy_codec.channels != 1) && (copy_codec.channels != 2)) {
534 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
535 "SetSecondarySendCodec() invalid number of channels");
536 return -1;
537 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000538 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
539 voe::Channel* channelPtr = ch.channel();
turaj@webrtc.org42259e72012-12-11 02:15:12 +0000540 if (channelPtr == NULL) {
541 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
542 "SetSecondarySendCodec() failed to locate channel");
543 return -1;
544 }
545 if (!AudioCodingModule::IsCodecValid(copy_codec)) {
546 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
547 "SetSecondarySendCodec() invalid codec");
548 return -1;
549 }
550 if (channelPtr->SetSecondarySendCodec(copy_codec, red_payload_type) != 0) {
551 _shared->SetLastError(VE_CANNOT_SET_SECONDARY_SEND_CODEC, kTraceError,
552 "SetSecondarySendCodec() failed to set secondary "
553 "send codec");
554 return -1;
555 }
556 return 0;
557}
558
559int VoECodecImpl::GetSecondarySendCodec(int channel, CodecInst& codec) {
560 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
561 "GetSecondarySendCodec(channel=%d, codec=?)", channel);
562 if (!_shared->statistics().Initialized()) {
563 _shared->SetLastError(VE_NOT_INITED, kTraceError);
564 return -1;
565 }
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000566 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
567 voe::Channel* channelPtr = ch.channel();
turaj@webrtc.org42259e72012-12-11 02:15:12 +0000568 if (channelPtr == NULL) {
569 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
570 "GetSecondarySendCodec() failed to locate channel");
571 return -1;
572 }
573 CodecInst acm_codec;
574 if (channelPtr->GetSecondarySendCodec(&acm_codec) != 0) {
575 _shared->SetLastError(VE_CANNOT_GET_SECONDARY_SEND_CODEC, kTraceError,
576 "GetSecondarySendCodec() failed to get secondary "
577 "send codec");
578 return -1;
579 }
580 ACMToExternalCodecRepresentation(codec, acm_codec);
581 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
582 VoEId(_shared->instance_id(), -1),
583 "GetSecondarySendCodec() => plname=%s, pacsize=%d, plfreq=%d, "
584 "channels=%d, rate=%d", codec.plname, codec.pacsize,
585 codec.plfreq, codec.channels, codec.rate);
586 return 0;
587}
588
589int VoECodecImpl::RemoveSecondarySendCodec(int channel) {
590 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
591 "RemoveSecondarySendCodec(channel=%d)", channel);
pbos@webrtc.org676ff1e2013-08-07 17:57:36 +0000592 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
593 voe::Channel* channelPtr = ch.channel();
turaj@webrtc.org42259e72012-12-11 02:15:12 +0000594 if (channelPtr == NULL) {
595 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
596 "RemoveSecondarySendCodec() failed to locate "
597 "channel");
598 return -1;
599 }
600 channelPtr->RemoveSecondarySendCodec();
601 return 0;
602}
603
niklase@google.com470e71d2011-07-07 08:21:25 +0000604#endif // WEBRTC_VOICE_ENGINE_CODEC_API
605
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000606} // namespace webrtc