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