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/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"
19
20 namespace webrtc
21 {
22
GetInterface(VoiceEngine * voiceEngine)23 VoECodec* 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 }
32 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
33 s->AddRef();
34 return s;
35 #endif
36 }
37
38 #ifdef WEBRTC_VOICE_ENGINE_CODEC_API
39
VoECodecImpl(voe::SharedData * shared)40 VoECodecImpl::VoECodecImpl(voe::SharedData* shared) : _shared(shared)
41 {
42 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
43 "VoECodecImpl() - ctor");
44 }
45
~VoECodecImpl()46 VoECodecImpl::~VoECodecImpl()
47 {
48 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
49 "~VoECodecImpl() - dtor");
50 }
51
NumOfCodecs()52 int VoECodecImpl::NumOfCodecs()
53 {
54 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
55 "NumOfCodecs()");
56
57 // Number of supported codecs in the ACM
58 uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
59
60 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
61 VoEId(_shared->instance_id(), -1),
62 "NumOfCodecs() => %u", nSupportedCodecs);
63 return (nSupportedCodecs);
64 }
65
GetCodec(int index,CodecInst & codec)66 int VoECodecImpl::GetCodec(int index, CodecInst& codec)
67 {
68 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
69 "GetCodec(index=%d, codec=?)", index);
70 CodecInst acmCodec;
71 if (AudioCodingModule::Codec(index, &acmCodec)
72 == -1)
73 {
74 _shared->SetLastError(VE_INVALID_LISTNR, kTraceError,
75 "GetCodec() invalid index");
76 return -1;
77 }
78 ACMToExternalCodecRepresentation(codec, acmCodec);
79 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);
84 return 0;
85 }
86
SetSendCodec(int channel,const CodecInst & codec)87 int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec)
88 {
89 CodecInst copyCodec;
90 ExternalToACMCodecRepresentation(copyCodec, codec);
91
92 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
93 "SetSendCodec(channel=%d, codec)", channel);
94 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
95 "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);
98 if (!_shared->statistics().Initialized())
99 {
100 _shared->SetLastError(VE_NOT_INITED, kTraceError);
101 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 {
107 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
108 "SetSendCodec() invalid L16 packet size");
109 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 {
115 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
116 "SetSendCodec() invalid codec name");
117 return -1;
118 }
119 if ((copyCodec.channels != 1) && (copyCodec.channels != 2))
120 {
121 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
122 "SetSendCodec() invalid number of channels");
123 return -1;
124 }
125 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
126 voe::Channel* channelPtr = ch.channel();
127 if (channelPtr == NULL)
128 {
129 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
130 "GetSendCodec() failed to locate channel");
131 return -1;
132 }
133 if (!AudioCodingModule::IsCodecValid(
134 (CodecInst&) copyCodec))
135 {
136 _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
137 "SetSendCodec() invalid codec");
138 return -1;
139 }
140 if (channelPtr->SetSendCodec(copyCodec) != 0)
141 {
142 _shared->SetLastError(VE_CANNOT_SET_SEND_CODEC, kTraceError,
143 "SetSendCodec() failed to set send codec");
144 return -1;
145 }
146
147 return 0;
148 }
149
GetSendCodec(int channel,CodecInst & codec)150 int VoECodecImpl::GetSendCodec(int channel, CodecInst& codec)
151 {
152 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
153 "GetSendCodec(channel=%d, codec=?)", channel);
154 if (!_shared->statistics().Initialized())
155 {
156 _shared->SetLastError(VE_NOT_INITED, kTraceError);
157 return -1;
158 }
159 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
160 voe::Channel* channelPtr = ch.channel();
161 if (channelPtr == NULL)
162 {
163 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
164 "GetSendCodec() failed to locate channel");
165 return -1;
166 }
167 CodecInst acmCodec;
168 if (channelPtr->GetSendCodec(acmCodec) != 0)
169 {
170 _shared->SetLastError(VE_CANNOT_GET_SEND_CODEC, kTraceError,
171 "GetSendCodec() failed to get send codec");
172 return -1;
173 }
174 ACMToExternalCodecRepresentation(codec, acmCodec);
175 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);
180 return 0;
181 }
182
GetRecCodec(int channel,CodecInst & codec)183 int VoECodecImpl::GetRecCodec(int channel, CodecInst& codec)
184 {
185 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
186 "GetRecCodec(channel=%d, codec=?)", channel);
187 if (!_shared->statistics().Initialized())
188 {
189 _shared->SetLastError(VE_NOT_INITED, kTraceError);
190 return -1;
191 }
192 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
193 voe::Channel* channelPtr = ch.channel();
194 if (channelPtr == NULL)
195 {
196 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
197 "GetRecCodec() failed to locate channel");
198 return -1;
199 }
200 CodecInst acmCodec;
201 if (channelPtr->GetRecCodec(acmCodec) != 0)
202 {
203 _shared->SetLastError(VE_CANNOT_GET_REC_CODEC, kTraceError,
204 "GetRecCodec() failed to get received codec");
205 return -1;
206 }
207 ACMToExternalCodecRepresentation(codec, acmCodec);
208 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);
213 return 0;
214 }
215
SetRecPayloadType(int channel,const CodecInst & codec)216 int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec)
217 {
218 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
219 "SetRecPayloadType(channel=%d, codec)", channel);
220 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
221 "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);
224 if (!_shared->statistics().Initialized())
225 {
226 _shared->SetLastError(VE_NOT_INITED, kTraceError);
227 return -1;
228 }
229 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
230 voe::Channel* channelPtr = ch.channel();
231 if (channelPtr == NULL)
232 {
233 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
234 "GetRecPayloadType() failed to locate channel");
235 return -1;
236 }
237 return channelPtr->SetRecPayloadType(codec);
238 }
239
GetRecPayloadType(int channel,CodecInst & codec)240 int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec)
241 {
242 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
243 "GetRecPayloadType(channel=%d, codec)", channel);
244 if (!_shared->statistics().Initialized())
245 {
246 _shared->SetLastError(VE_NOT_INITED, kTraceError);
247 return -1;
248 }
249 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
250 voe::Channel* channelPtr = ch.channel();
251 if (channelPtr == NULL)
252 {
253 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
254 "GetRecPayloadType() failed to locate channel");
255 return -1;
256 }
257 return channelPtr->GetRecPayloadType(codec);
258 }
259
SetSendCNPayloadType(int channel,int type,PayloadFrequencies frequency)260 int VoECodecImpl::SetSendCNPayloadType(int channel, int type,
261 PayloadFrequencies frequency)
262 {
263 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
264 "SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)",
265 channel, type, frequency);
266 if (!_shared->statistics().Initialized())
267 {
268 _shared->SetLastError(VE_NOT_INITED, kTraceError);
269 return -1;
270 }
271 if (type < 96 || type > 127)
272 {
273 // Only allow dynamic range: 96 to 127
274 _shared->SetLastError(VE_INVALID_PLTYPE, kTraceError,
275 "SetSendCNPayloadType() invalid payload type");
276 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.
283 _shared->SetLastError(VE_INVALID_PLFREQ, kTraceError,
284 "SetSendCNPayloadType() invalid payload frequency");
285 return -1;
286 }
287 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
288 voe::Channel* channelPtr = ch.channel();
289 if (channelPtr == NULL)
290 {
291 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
292 "SetSendCNPayloadType() failed to locate channel");
293 return -1;
294 }
295 return channelPtr->SetSendCNPayloadType(type, frequency);
296 }
297
SetFECStatus(int channel,bool enable)298 int 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
GetFECStatus(int channel,bool & enabled)315 int 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
SetVADStatus(int channel,bool enable,VadModes mode,bool disableDTX)333 int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode,
334 bool disableDTX)
335 {
336 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
337 "SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)",
338 channel, enable, mode, disableDTX);
339
340 if (!_shared->statistics().Initialized())
341 {
342 _shared->SetLastError(VE_NOT_INITED, kTraceError);
343 return -1;
344 }
345 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
346 voe::Channel* channelPtr = ch.channel();
347 if (channelPtr == NULL)
348 {
349 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
350 "SetVADStatus failed to locate channel");
351 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;
369 }
370 return channelPtr->SetVADStatus(enable, vadMode, disableDTX);
371 }
372
GetVADStatus(int channel,bool & enabled,VadModes & mode,bool & disabledDTX)373 int VoECodecImpl::GetVADStatus(int channel, bool& enabled, VadModes& mode,
374 bool& disabledDTX)
375 {
376 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
377 "GetVADStatus(channel=%i)", channel);
378
379 if (!_shared->statistics().Initialized())
380 {
381 _shared->SetLastError(VE_NOT_INITED, kTraceError);
382 return -1;
383 }
384 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
385 voe::Channel* channelPtr = ch.channel();
386 if (channelPtr == NULL)
387 {
388 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
389 "GetVADStatus failed to locate channel");
390 return -1;
391 }
392
393 ACMVADMode vadMode;
394 int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX);
395
396 if (ret != 0)
397 {
398 _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
399 "GetVADStatus failed to get VAD mode");
400 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;
416 }
417
418 return 0;
419 }
420
ACMToExternalCodecRepresentation(CodecInst & toInst,const CodecInst & fromInst)421 void 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
ExternalToACMCodecRepresentation(CodecInst & toInst,const CodecInst & fromInst)460 void 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
SetSecondarySendCodec(int channel,const CodecInst & codec,int red_payload_type)499 int 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 }
538 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
539 voe::Channel* channelPtr = ch.channel();
540 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
GetSecondarySendCodec(int channel,CodecInst & codec)559 int 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 }
566 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
567 voe::Channel* channelPtr = ch.channel();
568 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
RemoveSecondarySendCodec(int channel)589 int VoECodecImpl::RemoveSecondarySendCodec(int channel) {
590 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
591 "RemoveSecondarySendCodec(channel=%d)", channel);
592 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
593 voe::Channel* channelPtr = ch.channel();
594 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
604 #endif // WEBRTC_VOICE_ENGINE_CODEC_API
605
606 } // namespace webrtc
607