blob: b0e41065dfcf2e8ea3b95d78beb47be51bdc959c [file] [log] [blame]
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "voe_codec_impl.h"
#include "audio_coding_module.h"
#include "channel.h"
#include "critical_section_wrapper.h"
#include "trace.h"
#include "voe_errors.h"
#include "voice_engine_impl.h"
namespace webrtc
{
VoECodec* VoECodec::GetInterface(VoiceEngine* voiceEngine)
{
#ifndef WEBRTC_VOICE_ENGINE_CODEC_API
return NULL;
#else
if (NULL == voiceEngine)
{
return NULL;
}
VoiceEngineImpl* s =
reinterpret_cast<VoiceEngineImpl*> (voiceEngine);
VoECodecImpl* d = s;
(*d)++;
return (d);
#endif
}
#ifdef WEBRTC_VOICE_ENGINE_CODEC_API
VoECodecImpl::VoECodecImpl()
{
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
"VoECodecImpl() - ctor");
}
VoECodecImpl::~VoECodecImpl()
{
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
"~VoECodecImpl() - dtor");
}
int VoECodecImpl::Release()
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"VoECodecImpl::Release()");
(*this)--;
int refCount = GetCount();
if (refCount < 0)
{
Reset();
_engineStatistics.SetLastError(VE_INTERFACE_NOT_FOUND,
kTraceWarning);
return (-1);
}
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
"VoECodecImpl reference counter = %d", refCount);
return (refCount);
}
int VoECodecImpl::NumOfCodecs()
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"NumOfCodecs()");
// Number of supported codecs in the ACM
WebRtc_UWord8 nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
"NumOfCodecs() => %u", nSupportedCodecs);
return (nSupportedCodecs);
}
int VoECodecImpl::GetCodec(int index, CodecInst& codec)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"GetCodec(index=%d, codec=?)", index);
CodecInst acmCodec;
if (AudioCodingModule::Codec(index, (CodecInst&) acmCodec)
== -1)
{
_engineStatistics.SetLastError(VE_INVALID_LISTNR, kTraceError,
"GetCodec() invalid index");
return -1;
}
ACMToExternalCodecRepresentation(codec, acmCodec);
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
"GetCodec() => plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
"channels=%d, rate=%d", codec.plname, codec.pacsize,
codec.plfreq, codec.pltype, codec.channels, codec.rate);
return 0;
}
int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec)
{
CodecInst copyCodec;
ExternalToACMCodecRepresentation(copyCodec, codec);
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetSendCodec(channel=%d, codec)", channel);
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"codec: plname=%s, pacsize=%d, plfreq=%d, pltype=%d, "
"channels=%d, rate=%d", codec.plname, codec.pacsize,
codec.plfreq, codec.pltype, codec.channels, codec.rate);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
// External sanity checks performed outside the ACM
if ((STR_CASE_CMP(copyCodec.plname, "L16") == 0) &&
(copyCodec.pacsize >= 960))
{
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetSendCodec() invalid L16 packet "
"size");
return -1;
}
if (!STR_CASE_CMP(copyCodec.plname, "CN")
|| !STR_CASE_CMP(copyCodec.plname, "TELEPHONE-EVENT")
|| !STR_CASE_CMP(copyCodec.plname, "RED"))
{
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetSendCodec() invalid codec name");
return -1;
}
if ((copyCodec.channels != 1) && (copyCodec.channels != 2))
{
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetSendCodec() invalid number of "
"channels");
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetSendCodec() failed to locate "
"channel");
return -1;
}
if (!AudioCodingModule::IsCodecValid(
(CodecInst&) copyCodec))
{
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetSendCodec() invalid codec");
return -1;
}
if (channelPtr->SetSendCodec(copyCodec) != 0)
{
_engineStatistics.SetLastError(VE_CANNOT_SET_SEND_CODEC,
kTraceError,
"SetSendCodec() failed to set send "
"codec");
return -1;
}
// Need to check if we should change APM settings for mono/stereo.
// We'll check all channels (sending or not), so we don't have to
// check this again when starting/stopping sending.
voe::ScopedChannel sc2(_channelManager);
void* iterator(NULL);
channelPtr = sc2.GetFirstChannel(iterator);
int maxNumChannels = 1;
while (channelPtr != NULL)
{
CodecInst tmpCdc;
channelPtr->GetSendCodec(tmpCdc);
if (tmpCdc.channels > maxNumChannels)
maxNumChannels = tmpCdc.channels;
channelPtr = sc2.GetNextChannel(iterator);
}
// Reuse the currently set number of capture channels. We need to wait
// until receiving a frame to determine the true number.
//
// TODO(andrew): AudioProcessing will return an error if there are more
// output than input channels (it doesn't want to produce fake channels).
// This will happen with a stereo codec and a device which doesn't support
// stereo. AudioCoding should probably do the faking; look into how to
// handle this case properly.
if (_audioProcessingModulePtr->set_num_channels(
_audioProcessingModulePtr->num_input_channels(),
maxNumChannels) != 0)
{
_engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError,
"Init() failed to set APM channels for the send audio stream");
return -1;
}
return 0;
}
int VoECodecImpl::GetSendCodec(int channel, CodecInst& codec)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"GetSendCodec(channel=%d, codec=?)", channel);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetSendCodec() failed to locate "
"channel");
return -1;
}
CodecInst acmCodec;
if (channelPtr->GetSendCodec(acmCodec) != 0)
{
_engineStatistics.SetLastError(VE_CANNOT_GET_SEND_CODEC, kTraceError,
"GetSendCodec() failed to get send "
"codec");
return -1;
}
ACMToExternalCodecRepresentation(codec, acmCodec);
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
"GetSendCodec() => plname=%s, pacsize=%d, plfreq=%d, "
"channels=%d, rate=%d", codec.plname, codec.pacsize,
codec.plfreq, codec.channels, codec.rate);
return 0;
}
int VoECodecImpl::GetRecCodec(int channel, CodecInst& codec)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"GetRecCodec(channel=%d, codec=?)", channel);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetRecCodec() failed to locate "
"channel");
return -1;
}
CodecInst acmCodec;
if (channelPtr->GetRecCodec(acmCodec) != 0)
{
_engineStatistics.SetLastError(VE_CANNOT_GET_REC_CODEC, kTraceError,
"GetRecCodec() failed to get received "
"codec");
return -1;
}
ACMToExternalCodecRepresentation(codec, acmCodec);
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
"GetRecCodec() => plname=%s, pacsize=%d, plfreq=%d, "
"channels=%d, rate=%d", codec.plname, codec.pacsize,
codec.plfreq, codec.channels, codec.rate);
return 0;
}
int VoECodecImpl::SetAMREncFormat(int channel, AmrMode mode)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetAMREncFormat(channel=%d, mode=%d)", channel, mode);
#ifdef WEBRTC_CODEC_GSMAMR
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetAMREncFormat() failed to locate "
"channel");
return -1;
}
return channelPtr->SetAMREncFormat(mode);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetAMREncFormat() AMR codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetAMRDecFormat(int channel, AmrMode mode)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetAMRDecFormat(channel=%i, mode=%i)", channel, mode);
#ifdef WEBRTC_CODEC_GSMAMR
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetAMRDecFormat() failed to locate "
"channel");
return -1;
}
return channelPtr->SetAMRDecFormat(mode);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetAMRDecFormat() AMR codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetAMRWbEncFormat(int channel, AmrMode mode)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetAMRWbEncFormat(channel=%d, mode=%d)", channel, mode);
ANDROID_NOT_SUPPORTED(_engineStatistics);
IPHONE_NOT_SUPPORTED();
#ifdef WEBRTC_CODEC_GSMAMRWB
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetAMRWbEncFormat() failed to locate "
"channel");
return -1;
}
return channelPtr->SetAMRWbEncFormat(mode);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetAMRWbEncFormat() AMR-wb codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetAMRWbDecFormat(int channel, AmrMode mode)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetAMRWbDecFormat(channel=%i, mode=%i)", channel, mode);
ANDROID_NOT_SUPPORTED(_engineStatistics);
IPHONE_NOT_SUPPORTED();
#ifdef WEBRTC_CODEC_GSMAMRWB
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetAMRWbDecFormat() failed to locate "
"channel");
return -1;
}
return channelPtr->SetAMRWbDecFormat(mode);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetAMRWbDecFormat() AMR-wb codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetRecPayloadType(int channel, const CodecInst& codec)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetRecPayloadType(channel=%d, codec)", channel);
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"codec: plname=%s, plfreq=%d, pltype=%d, channels=%u, "
"pacsize=%d, rate=%d", codec.plname, codec.plfreq, codec.pltype,
codec.channels, codec.pacsize, codec.rate);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetRecPayloadType() failed to locate "
"channel");
return -1;
}
return channelPtr->SetRecPayloadType(codec);
}
int VoECodecImpl::GetRecPayloadType(int channel, CodecInst& codec)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"GetRecPayloadType(channel=%d, codec)", channel);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetRecPayloadType() failed to locate "
"channel");
return -1;
}
return channelPtr->GetRecPayloadType(codec);
}
int VoECodecImpl::SetSendCNPayloadType(int channel, int type,
PayloadFrequencies frequency)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetSendCNPayloadType(channel=%d, type=%d, frequency=%d)",
channel, type, frequency);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
if (type < 96 || type > 127)
{
// Only allow dynamic range: 96 to 127
_engineStatistics.SetLastError(VE_INVALID_PLTYPE, kTraceError,
"SetSendCNPayloadType() invalid payload "
"type");
return -1;
}
if ((frequency != kFreq16000Hz) && (frequency != kFreq32000Hz))
{
// It is not possible to modify the payload type for CN/8000.
// We only allow modification of the CN payload type for CN/16000
// and CN/32000.
_engineStatistics.SetLastError(VE_INVALID_PLFREQ, kTraceError,
"SetSendCNPayloadType() invalid payload"
" frequency");
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetSendCNPayloadType() failed to "
"locate channel");
return -1;
}
if (channelPtr->Sending())
{
_engineStatistics.SetLastError(VE_SENDING, kTraceError,
"SetSendCNPayloadType unable so set "
"payload type while sending");
return -1;
}
return channelPtr->SetSendCNPayloadType(type, frequency);
}
int VoECodecImpl::SetISACInitTargetRate(int channel, int rateBps,
bool useFixedFrameSize)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetISACInitTargetRate(channel=%d, rateBps=%d, "
"useFixedFrameSize=%d)", channel, rateBps, useFixedFrameSize);
ANDROID_NOT_SUPPORTED(_engineStatistics);
IPHONE_NOT_SUPPORTED();
#ifdef WEBRTC_CODEC_ISAC
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetISACInitTargetRate() failed to "
"locate channel");
return -1;
}
return channelPtr->SetISACInitTargetRate(rateBps, useFixedFrameSize);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetISACInitTargetRate() iSAC codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetISACMaxRate(int channel, int rateBps)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetISACMaxRate(channel=%d, rateBps=%d)", channel, rateBps);
ANDROID_NOT_SUPPORTED(_engineStatistics);
IPHONE_NOT_SUPPORTED();
#ifdef WEBRTC_CODEC_ISAC
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetISACMaxRate() failed to locate "
"channel");
return -1;
}
return channelPtr->SetISACMaxRate(rateBps);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetISACMaxRate() iSAC codec is not "
"supported");
return -1;
#endif
}
int VoECodecImpl::SetISACMaxPayloadSize(int channel, int sizeBytes)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetISACMaxPayloadSize(channel=%d, sizeBytes=%d)", channel,
sizeBytes);
ANDROID_NOT_SUPPORTED(_engineStatistics);
IPHONE_NOT_SUPPORTED();
#ifdef WEBRTC_CODEC_ISAC
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetISACMaxPayloadSize() failed to "
"locate channel");
return -1;
}
return channelPtr->SetISACMaxPayloadSize(sizeBytes);
#else
_engineStatistics.SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetISACMaxPayloadSize() iSAC codec is not "
"supported");
return -1;
#endif
return 0;
}
int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode,
bool disableDTX)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"SetVADStatus(channel=%i, enable=%i, mode=%i, disableDTX=%i)",
channel, enable, mode, disableDTX);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetVADStatus failed to locate channel");
return -1;
}
ACMVADMode vadMode(VADNormal);
switch (mode)
{
case kVadConventional:
vadMode = VADNormal;
break;
case kVadAggressiveLow:
vadMode = VADLowBitrate;
break;
case kVadAggressiveMid:
vadMode = VADAggr;
break;
case kVadAggressiveHigh:
vadMode = VADVeryAggr;
break;
default:
_engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetVADStatus() invalid VAD mode");
return -1;
}
return channelPtr->SetVADStatus(enable, vadMode, disableDTX);
}
int VoECodecImpl::GetVADStatus(int channel, bool& enabled, VadModes& mode,
bool& disabledDTX)
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
"GetVADStatus(channel=%i)", channel);
if (!_engineStatistics.Initialized())
{
_engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ScopedChannel sc(_channelManager, channel);
voe::Channel* channelPtr = sc.ChannelPtr();
if (channelPtr == NULL)
{
_engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetVADStatus failed to locate channel");
return -1;
}
ACMVADMode vadMode;
int ret = channelPtr->GetVADStatus(enabled, vadMode, disabledDTX);
if (ret != 0)
{
_engineStatistics.SetLastError(VE_INVALID_OPERATION, kTraceError,
"GetVADStatus failed to get VAD mode");
return -1;
}
switch (vadMode)
{
case VADNormal:
mode = kVadConventional;
break;
case VADLowBitrate:
mode = kVadAggressiveLow;
break;
case VADAggr:
mode = kVadAggressiveMid;
break;
case VADVeryAggr:
mode = kVadAggressiveHigh;
break;
default:
_engineStatistics.SetLastError(VE_AUDIO_CODING_MODULE_ERROR,
kTraceError,
"GetVADStatus() invalid VAD mode");
return -1;
}
return 0;
}
void VoECodecImpl::ACMToExternalCodecRepresentation(CodecInst& toInst,
const CodecInst& fromInst)
{
toInst = fromInst;
if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
{
if (fromInst.plfreq == 12000)
{
if (fromInst.pacsize == 320)
{
toInst.pacsize = 240;
}
else if (fromInst.pacsize == 640)
{
toInst.pacsize = 480;
}
else if (fromInst.pacsize == 960)
{
toInst.pacsize = 720;
}
}
else if (fromInst.plfreq == 24000)
{
if (fromInst.pacsize == 640)
{
toInst.pacsize = 480;
}
else if (fromInst.pacsize == 1280)
{
toInst.pacsize = 960;
}
else if (fromInst.pacsize == 1920)
{
toInst.pacsize = 1440;
}
}
}
}
void VoECodecImpl::ExternalToACMCodecRepresentation(CodecInst& toInst,
const CodecInst& fromInst)
{
toInst = fromInst;
if (STR_CASE_CMP(fromInst.plname,"SILK") == 0)
{
if (fromInst.plfreq == 12000)
{
if (fromInst.pacsize == 240)
{
toInst.pacsize = 320;
}
else if (fromInst.pacsize == 480)
{
toInst.pacsize = 640;
}
else if (fromInst.pacsize == 720)
{
toInst.pacsize = 960;
}
}
else if (fromInst.plfreq == 24000)
{
if (fromInst.pacsize == 480)
{
toInst.pacsize = 640;
}
else if (fromInst.pacsize == 960)
{
toInst.pacsize = 1280;
}
else if (fromInst.pacsize == 1440)
{
toInst.pacsize = 1920;
}
}
}
}
#endif // WEBRTC_VOICE_ENGINE_CODEC_API
} // namespace webrtc