blob: 4df97c3ee2d1ba5d59da37d3abb4723d644ece4d [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
11#include "voe_codec_impl.h"
12
13#include "audio_coding_module.h"
14#include "channel.h"
15#include "critical_section_wrapper.h"
16#include "trace.h"
17#include "voe_errors.h"
18#include "voice_engine_impl.h"
19
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 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000125 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000126 voe::Channel* channelPtr = sc.ChannelPtr();
127 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 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000159 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000160 voe::Channel* channelPtr = sc.ChannelPtr();
161 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 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000192 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 voe::Channel* channelPtr = sc.ChannelPtr();
194 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
216int VoECodecImpl::SetAMREncFormat(int channel, AmrMode mode)
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 "SetAMREncFormat(channel=%d, mode=%d)", channel, mode);
tina.legrand@webrtc.orgeb232ce2012-10-12 12:50:14 +0000220#ifdef WEBRTC_CODEC_AMR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000221 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000222 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000223 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000224 return -1;
225 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000226 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000227 voe::Channel* channelPtr = sc.ChannelPtr();
228 if (channelPtr == NULL)
229 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000230 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
231 "SetAMREncFormat() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000232 return -1;
233 }
234 return channelPtr->SetAMREncFormat(mode);
235#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000236 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
237 "SetAMREncFormat() AMR codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000238 return -1;
239#endif
240}
241
242int VoECodecImpl::SetAMRDecFormat(int channel, AmrMode mode)
243{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000244 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000245 "SetAMRDecFormat(channel=%i, mode=%i)", channel, mode);
tina.legrand@webrtc.orgeb232ce2012-10-12 12:50:14 +0000246#ifdef WEBRTC_CODEC_AMR
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000247 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000248 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000249 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000250 return -1;
251 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000252 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000253 voe::Channel* channelPtr = sc.ChannelPtr();
254 if (channelPtr == NULL)
255 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000256 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
257 "SetAMRDecFormat() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000258 return -1;
259 }
260 return channelPtr->SetAMRDecFormat(mode);
261#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000262 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
263 "SetAMRDecFormat() AMR codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000264 return -1;
265#endif
266}
267
268int VoECodecImpl::SetAMRWbEncFormat(int channel, AmrMode mode)
269{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000270 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000271 "SetAMRWbEncFormat(channel=%d, mode=%d)", channel, mode);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000272 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000273 IPHONE_NOT_SUPPORTED(_shared->statistics());
tina.legrand@webrtc.orgeb232ce2012-10-12 12:50:14 +0000274#ifdef WEBRTC_CODEC_AMRWB
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000275 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000276 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000277 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000278 return -1;
279 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000280 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000281 voe::Channel* channelPtr = sc.ChannelPtr();
282 if (channelPtr == NULL)
283 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000284 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
285 "SetAMRWbEncFormat() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 return -1;
287 }
288 return channelPtr->SetAMRWbEncFormat(mode);
289#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000290 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
291 "SetAMRWbEncFormat() AMR-wb codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000292 return -1;
293#endif
294}
295
296int VoECodecImpl::SetAMRWbDecFormat(int channel, AmrMode mode)
297{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000298 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 "SetAMRWbDecFormat(channel=%i, mode=%i)", channel, mode);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000300 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000301 IPHONE_NOT_SUPPORTED(_shared->statistics());
tina.legrand@webrtc.orgeb232ce2012-10-12 12:50:14 +0000302#ifdef WEBRTC_CODEC_AMRWB
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000303 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000304 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000305 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000306 return -1;
307 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000308 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 voe::Channel* channelPtr = sc.ChannelPtr();
310 if (channelPtr == NULL)
311 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000312 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
313 "SetAMRWbDecFormat() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000314 return -1;
315 }
316 return channelPtr->SetAMRWbDecFormat(mode);
317#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000318 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
319 "SetAMRWbDecFormat() AMR-wb codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 return -1;
321#endif
322}
323
324int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec)
325{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000326 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 "SetRecPayloadType(channel=%d, codec)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000328 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 "codec: plname=%s, plfreq=%d, pltype=%d, channels=%u, "
330 "pacsize=%d, rate=%d", codec.plname, codec.plfreq, codec.pltype,
331 codec.channels, codec.pacsize, codec.rate);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000332 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000334 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 return -1;
336 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000337 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 voe::Channel* channelPtr = sc.ChannelPtr();
339 if (channelPtr == NULL)
340 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000341 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
342 "GetRecPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 return -1;
344 }
345 return channelPtr->SetRecPayloadType(codec);
346}
347
348int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec)
349{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000350 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 "GetRecPayloadType(channel=%d, codec)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000352 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000354 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 return -1;
356 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000357 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000358 voe::Channel* channelPtr = sc.ChannelPtr();
359 if (channelPtr == NULL)
360 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000361 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
362 "GetRecPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000363 return -1;
364 }
365 return channelPtr->GetRecPayloadType(codec);
366}
367
368int VoECodecImpl::SetSendCNPayloadType(int channel, int type,
369 PayloadFrequencies frequency)
370{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000371 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000372 "SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)",
373 channel, type, frequency);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000374 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000375 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000376 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000377 return -1;
378 }
379 if (type < 96 || type > 127)
380 {
381 // Only allow dynamic range: 96 to 127
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000382 _shared->SetLastError(VE_INVALID_PLTYPE, kTraceError,
383 "SetSendCNPayloadType() invalid payload type");
niklase@google.com470e71d2011-07-07 08:21:25 +0000384 return -1;
385 }
386 if ((frequency != kFreq16000Hz) && (frequency != kFreq32000Hz))
387 {
388 // It is not possible to modify the payload type for CN/8000.
389 // We only allow modification of the CN payload type for CN/16000
390 // and CN/32000.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000391 _shared->SetLastError(VE_INVALID_PLFREQ, kTraceError,
392 "SetSendCNPayloadType() invalid payload frequency");
niklase@google.com470e71d2011-07-07 08:21:25 +0000393 return -1;
394 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000395 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000396 voe::Channel* channelPtr = sc.ChannelPtr();
397 if (channelPtr == NULL)
398 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000399 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
400 "SetSendCNPayloadType() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000401 return -1;
402 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000403 return channelPtr->SetSendCNPayloadType(type, frequency);
404}
405
406int VoECodecImpl::SetISACInitTargetRate(int channel, int rateBps,
407 bool useFixedFrameSize)
408{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000409 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 "SetISACInitTargetRate(channel=%d, rateBps=%d, "
411 "useFixedFrameSize=%d)", channel, rateBps, useFixedFrameSize);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000412 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000413 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000414#ifdef WEBRTC_CODEC_ISAC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000415 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000417 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000418 return -1;
419 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000420 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 voe::Channel* channelPtr = sc.ChannelPtr();
422 if (channelPtr == NULL)
423 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000424 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
425 "SetISACInitTargetRate() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000426 return -1;
427 }
428 return channelPtr->SetISACInitTargetRate(rateBps, useFixedFrameSize);
429#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000430 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
431 "SetISACInitTargetRate() iSAC codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 return -1;
433#endif
434}
435
436int VoECodecImpl::SetISACMaxRate(int channel, int rateBps)
437{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000438 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000439 "SetISACMaxRate(channel=%d, rateBps=%d)", channel, rateBps);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000440 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000441 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000442#ifdef WEBRTC_CODEC_ISAC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000443 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000444 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000445 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 return -1;
447 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000448 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000449 voe::Channel* channelPtr = sc.ChannelPtr();
450 if (channelPtr == NULL)
451 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000452 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
453 "SetISACMaxRate() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000454 return -1;
455 }
456 return channelPtr->SetISACMaxRate(rateBps);
457#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000458 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
459 "SetISACMaxRate() iSAC codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000460 return -1;
461#endif
462}
463
464int VoECodecImpl::SetISACMaxPayloadSize(int channel, int sizeBytes)
465{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000466 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000467 "SetISACMaxPayloadSize(channel=%d, sizeBytes=%d)", channel,
468 sizeBytes);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000469 ANDROID_NOT_SUPPORTED(_shared->statistics());
sjlee@webrtc.org4b425082012-09-10 17:58:21 +0000470 IPHONE_NOT_SUPPORTED(_shared->statistics());
niklase@google.com470e71d2011-07-07 08:21:25 +0000471#ifdef WEBRTC_CODEC_ISAC
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000472 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000473 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000474 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000475 return -1;
476 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000477 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000478 voe::Channel* channelPtr = sc.ChannelPtr();
479 if (channelPtr == NULL)
480 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000481 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
482 "SetISACMaxPayloadSize() failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000483 return -1;
484 }
485 return channelPtr->SetISACMaxPayloadSize(sizeBytes);
486#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000487 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
488 "SetISACMaxPayloadSize() iSAC codec is not supported");
niklase@google.com470e71d2011-07-07 08:21:25 +0000489 return -1;
490#endif
491 return 0;
492}
493
494int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode,
495 bool disableDTX)
496{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000497 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 "SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)",
499 channel, enable, mode, disableDTX);
500
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000501 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000502 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000503 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000504 return -1;
505 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000506 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 voe::Channel* channelPtr = sc.ChannelPtr();
508 if (channelPtr == NULL)
509 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000510 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
511 "SetVADStatus failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000512 return -1;
513 }
514
515 ACMVADMode vadMode(VADNormal);
516 switch (mode)
517 {
518 case kVadConventional:
519 vadMode = VADNormal;
520 break;
521 case kVadAggressiveLow:
522 vadMode = VADLowBitrate;
523 break;
524 case kVadAggressiveMid:
525 vadMode = VADAggr;
526 break;
527 case kVadAggressiveHigh:
528 vadMode = VADVeryAggr;
529 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000530 }
531 return channelPtr->SetVADStatus(enable, vadMode, disableDTX);
532}
533
534int VoECodecImpl::GetVADStatus(int channel, bool& enabled, VadModes& mode,
535 bool& disabledDTX)
536{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000537 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000538 "GetVADStatus(channel=%i)", channel);
539
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000540 if (!_shared->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000542 _shared->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 return -1;
544 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000545 voe::ScopedChannel sc(_shared->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000546 voe::Channel* channelPtr = sc.ChannelPtr();
547 if (channelPtr == NULL)
548 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000549 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
550 "GetVADStatus failed to locate channel");
niklase@google.com470e71d2011-07-07 08:21:25 +0000551 return -1;
552 }
553
554 ACMVADMode vadMode;
555 int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX);
556
557 if (ret != 0)
558 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000559 _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
560 "GetVADStatus failed to get VAD mode");
niklase@google.com470e71d2011-07-07 08:21:25 +0000561 return -1;
562 }
563 switch (vadMode)
564 {
565 case VADNormal:
566 mode = kVadConventional;
567 break;
568 case VADLowBitrate:
569 mode = kVadAggressiveLow;
570 break;
571 case VADAggr:
572 mode = kVadAggressiveMid;
573 break;
574 case VADVeryAggr:
575 mode = kVadAggressiveHigh;
576 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000577 }
578
579 return 0;
580}
581
582void VoECodecImpl::ACMToExternalCodecRepresentation(CodecInst& toInst,
583 const CodecInst& fromInst)
584{
585 toInst = fromInst;
586 if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
587 {
588 if (fromInst.plfreq == 12000)
589 {
590 if (fromInst.pacsize == 320)
591 {
592 toInst.pacsize = 240;
593 }
594 else if (fromInst.pacsize == 640)
595 {
596 toInst.pacsize = 480;
597 }
598 else if (fromInst.pacsize == 960)
599 {
600 toInst.pacsize = 720;
601 }
602 }
603 else if (fromInst.plfreq == 24000)
604 {
605 if (fromInst.pacsize == 640)
606 {
607 toInst.pacsize = 480;
608 }
609 else if (fromInst.pacsize == 1280)
610 {
611 toInst.pacsize = 960;
612 }
613 else if (fromInst.pacsize == 1920)
614 {
615 toInst.pacsize = 1440;
616 }
617 }
618 }
619}
620
621void VoECodecImpl::ExternalToACMCodecRepresentation(CodecInst& toInst,
622 const CodecInst& fromInst)
623{
624 toInst = fromInst;
625 if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
626 {
627 if (fromInst.plfreq == 12000)
628 {
629 if (fromInst.pacsize == 240)
630 {
631 toInst.pacsize = 320;
632 }
633 else if (fromInst.pacsize == 480)
634 {
635 toInst.pacsize = 640;
636 }
637 else if (fromInst.pacsize == 720)
638 {
639 toInst.pacsize = 960;
640 }
641 }
642 else if (fromInst.plfreq == 24000)
643 {
644 if (fromInst.pacsize == 480)
645 {
646 toInst.pacsize = 640;
647 }
648 else if (fromInst.pacsize == 960)
649 {
650 toInst.pacsize = 1280;
651 }
652 else if (fromInst.pacsize == 1440)
653 {
654 toInst.pacsize = 1920;
655 }
656 }
657 }
658}
659
turaj@webrtc.org42259e72012-12-11 02:15:12 +0000660int VoECodecImpl::SetSecondarySendCodec(int channel, const CodecInst& codec,
661 int red_payload_type) {
662 CodecInst copy_codec;
663 ExternalToACMCodecRepresentation(copy_codec, codec);
664
665 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
666 "SetSecondarySendCodec(channel=%d, codec)", channel);
667 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
668 "codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
669 "channels=%d, rate=%d", codec.plname, codec.pacsize,
670 codec.plfreq, codec.pltype, codec.channels, codec.rate);
671 if (!_shared->statistics().Initialized()) {
672 _shared->SetLastError(VE_NOT_INITED, kTraceError);
673 return -1;
674 }
675
676 // External sanity checks performed outside the ACM
677 if ((STR_CASE_CMP(copy_codec.plname, "L16") == 0) &&
678 (copy_codec.pacsize >= 960)) {
679 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
680 "SetSecondarySendCodec() invalid L16 packet size");
681 return -1;
682 }
683
684 // None of the following codecs can be registered as the secondary encoder.
685 if (!STR_CASE_CMP(copy_codec.plname, "CN") ||
686 !STR_CASE_CMP(copy_codec.plname, "TELEPHONE-EVENT") ||
687 !STR_CASE_CMP(copy_codec.plname, "RED")) {
688 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
689 "SetSecondarySendCodec() invalid codec name");
690 return -1;
691 }
692
693 // Only mono and stereo are supported.
694 if ((copy_codec.channels != 1) && (copy_codec.channels != 2)) {
695 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
696 "SetSecondarySendCodec() invalid number of channels");
697 return -1;
698 }
699 voe::ScopedChannel sc(_shared->channel_manager(), channel);
700 voe::Channel* channelPtr = sc.ChannelPtr();
701 if (channelPtr == NULL) {
702 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
703 "SetSecondarySendCodec() failed to locate channel");
704 return -1;
705 }
706 if (!AudioCodingModule::IsCodecValid(copy_codec)) {
707 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
708 "SetSecondarySendCodec() invalid codec");
709 return -1;
710 }
711 if (channelPtr->SetSecondarySendCodec(copy_codec, red_payload_type) != 0) {
712 _shared->SetLastError(VE_CANNOT_SET_SECONDARY_SEND_CODEC, kTraceError,
713 "SetSecondarySendCodec() failed to set secondary "
714 "send codec");
715 return -1;
716 }
717 return 0;
718}
719
720int VoECodecImpl::GetSecondarySendCodec(int channel, CodecInst& codec) {
721 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
722 "GetSecondarySendCodec(channel=%d, codec=?)", channel);
723 if (!_shared->statistics().Initialized()) {
724 _shared->SetLastError(VE_NOT_INITED, kTraceError);
725 return -1;
726 }
727 voe::ScopedChannel sc(_shared->channel_manager(), channel);
728 voe::Channel* channelPtr = sc.ChannelPtr();
729 if (channelPtr == NULL) {
730 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
731 "GetSecondarySendCodec() failed to locate channel");
732 return -1;
733 }
734 CodecInst acm_codec;
735 if (channelPtr->GetSecondarySendCodec(&acm_codec) != 0) {
736 _shared->SetLastError(VE_CANNOT_GET_SECONDARY_SEND_CODEC, kTraceError,
737 "GetSecondarySendCodec() failed to get secondary "
738 "send codec");
739 return -1;
740 }
741 ACMToExternalCodecRepresentation(codec, acm_codec);
742 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
743 VoEId(_shared->instance_id(), -1),
744 "GetSecondarySendCodec() => plname=%s, pacsize=%d, plfreq=%d, "
745 "channels=%d, rate=%d", codec.plname, codec.pacsize,
746 codec.plfreq, codec.channels, codec.rate);
747 return 0;
748}
749
750int VoECodecImpl::RemoveSecondarySendCodec(int channel) {
751 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
752 "RemoveSecondarySendCodec(channel=%d)", channel);
753 voe::ScopedChannel sc(_shared->channel_manager(), channel);
754 voe::Channel* channelPtr = sc.ChannelPtr();
755 if (channelPtr == NULL) {
756 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
757 "RemoveSecondarySendCodec() failed to locate "
758 "channel");
759 return -1;
760 }
761 channelPtr->RemoveSecondarySendCodec();
762 return 0;
763}
764
niklase@google.com470e71d2011-07-07 08:21:25 +0000765#endif // WEBRTC_VOICE_ENGINE_CODEC_API
766
767} // namespace webrtc