webrtc/modules/audio_coding/main/source/acm_codec_database.cc

954 lines
30 KiB
C++

/*
* 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.
*/
// 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4267)
#include <stdio.h>
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "trace.h"
// Includes needed to get version info
// and to create the codecs
#include "acm_pcma.h"
#include "acm_pcmu.h"
#include "g711_interface.h"
#include "webrtc_neteq.h"
#include "webrtc_cng.h"
#include "acm_cng.h"
#ifdef WEBRTC_CODEC_AVT
#include "acm_dtmf_playout.h"
#endif
#ifdef WEBRTC_CODEC_RED
#include "acm_red.h"
#endif
#ifdef WEBRTC_CODEC_ILBC
#include "acm_ilbc.h"
#include "ilbc.h"
#endif
#ifdef WEBRTC_CODEC_ISAC
#include "acm_isac.h"
#include "acm_isac_macros.h"
#include "isac.h"
#endif
#ifdef WEBRTC_CODEC_ISACFX
#include "acm_isac.h"
#include "acm_isac_macros.h"
#include "isacfix.h"
#endif
#ifdef WEBRTC_CODEC_PCM16
#include "pcm16b.h"
#include "acm_pcm16b.h"
#endif
#ifdef WEBRTC_CODEC_G722
#include "acm_g722.h"
#include "g722_interface.h"
#endif
namespace webrtc
{
#define TEMPORARY_BUFFER_SIZE 500
bool ACMCodecDB::_isInitiated = false;
WebRtc_Word16 ACMCodecDB::_noOfCodecs = 0;
WebRtc_Word16 ACMCodecDB::_noNetEqDecoders = 0;
WebRtc_Word16 ACMCodecDB::_noPayloads = 0;
WebRtc_Word16 ACMCodecDB::isac = -1;
WebRtc_Word16 ACMCodecDB::isacswb = -1;
WebRtc_Word16 ACMCodecDB::pcm16b = -1;
WebRtc_Word16 ACMCodecDB::pcm16bwb = -1;
WebRtc_Word16 ACMCodecDB::pcm16bswb32 = -1;
WebRtc_Word16 ACMCodecDB::pcm16bswb48 = -1;
WebRtc_Word16 ACMCodecDB::pcmu = -1;
WebRtc_Word16 ACMCodecDB::pcma = -1;
WebRtc_Word16 ACMCodecDB::ilbc = -1;
WebRtc_Word16 ACMCodecDB::gsmAMR = -1;
WebRtc_Word16 ACMCodecDB::gsmAMRWB = -1;
WebRtc_Word16 ACMCodecDB::g722 = -1;
WebRtc_Word16 ACMCodecDB::g722_1_32 = -1;
WebRtc_Word16 ACMCodecDB::g722_1_24 = -1;
WebRtc_Word16 ACMCodecDB::g722_1_16 = -1;
WebRtc_Word16 ACMCodecDB::g722_1C_48 = -1;
WebRtc_Word16 ACMCodecDB::g722_1C_32 = -1;
WebRtc_Word16 ACMCodecDB::g722_1C_24 = -1;
WebRtc_Word16 ACMCodecDB::g729 = -1;
WebRtc_Word16 ACMCodecDB::gsmfr = -1;
WebRtc_Word16 ACMCodecDB::speex8 = -1;
WebRtc_Word16 ACMCodecDB::speex16 = -1;
WebRtc_Word16 ACMCodecDB::cnNB = -1;
WebRtc_Word16 ACMCodecDB::cnWB = -1;
WebRtc_Word16 ACMCodecDB::cnSWB = -1;
WebRtc_Word16 ACMCodecDB::avt = -1;
WebRtc_Word16 ACMCodecDB::red = -1;
WebRtc_UWord8 ACMCodecDB::_nrOfAllowedPacSizes[MAX_NR_OF_CODECS];
WebRtc_UWord16 ACMCodecDB::_allowedPacSizesSmpl[MAX_NR_OF_CODECS][MAX_NR_OF_PACSIZES];
CodecInst ACMCodecDB::_mycodecs[MAX_NR_OF_CODECS];
enum WebRtcNetEQDecoder ACMCodecDB::_netEqDecoders[MAX_NR_OF_CODECS];
WebRtc_Word8 ACMCodecDB::_versions[VERSION_SIZE];
WebRtc_UWord16 ACMCodecDB::_basicCodingBlockSmpl[MAX_NR_OF_CODECS];
WebRtc_UWord16 ACMCodecDB::_channelSupport[MAX_NR_OF_CODECS];
WebRtc_UWord32 ACMCodecDB::_versionStringSize = 0;
// We dynamically allocate some of the dynamic payload types to the defined codecs
// Note! There are a limited number of payload types. If more codecs are defined
// they will receive reserved fixed payload types (values 65-95).
static int kDynamicPayloadtypes[MAX_NR_OF_CODECS] = {
105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 95, 94, 93, 92, 91, 90, 89,
88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75,
74, 73, 72, 71, 70, 69, 68, 67, 66, 65
};
WebRtc_Word16
ACMCodecDB::Codec(
WebRtc_Word16 listnr,
CodecInst* codec_inst)
{
// Error check to se that listnr is between 0 and (_noOfCodecs - 1)
if ((listnr < 0) || (listnr >= _noOfCodecs))
{
return -1;
}
memcpy(codec_inst,&_mycodecs[listnr],sizeof(CodecInst));
return 0;
}
WebRtc_Word16
ACMCodecDB::CodecNumber(
const CodecInst* codecInst,
WebRtc_Word16& mirrorID,
WebRtc_Word8* errMessage,
WebRtc_Word16 maxErrMsgLenByte)
{
WebRtc_Word16 codecID = ACMCodecDB::CodecNumber(codecInst, mirrorID);
if((codecID < 0) && (errMessage != NULL))
{
WebRtc_Word8 myErrMsg[1000];
if (codecID == -10)
{
// Codec not supported
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, plname=%s is \
not a valid codec", codecInst->plname);
}
else if (codecID == -20)
{
// Sampling frequency doesn't match codec
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, plfreq=%d is \
not a valid frequency for the codec %s", codecInst->plfreq, codecInst->plname);
}
else if (codecID == -30)
{
// Wrong payload type for Comfort Noise
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, payload \
number %d is out of range for %s", codecInst->pltype, codecInst->plname);
}
else if (codecID == -40)
{
// Wrong payload type for RED
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, payload \
number %d is out of range for %s", codecInst->pltype, codecInst->plname);
}
else if (codecID == -50)
{
// Packet size is out of range for the codec
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, Packet \
size is out of range for %s", codecInst->plname);
}
else if (codecID == -60)
{
// Not a valid rate for the codec
sprintf(myErrMsg,
"Call to ACMCodecDB::CodecNumber failed, rate=%d \
is not a valid rate for %s", codecInst->rate, codecInst->plname);
}
else
{
// Other error
sprintf(myErrMsg,
"invalid codec parameters to be registered, \
ACMCodecDB::CodecNumber failed");
}
strncpy(errMessage, myErrMsg, maxErrMsgLenByte - 1);
// make sure that the massage is null-terminated.
errMessage[maxErrMsgLenByte - 1] = '\0';
}
return codecID;
}
WebRtc_Word16
ACMCodecDB::CodecNumber(
const CodecInst* codec_inst,
WebRtc_Word16& mirrorID)
{
WebRtc_Word16 codecNumber = -1;
WebRtc_Word16 nameMatch = 0;
// Find a matching payload name and frequency in the codec list
// Need to check both since some codecs have several codec entries with
// Different frequencies (like iSAC)
for(WebRtc_Word16 i = 0; i < _noOfCodecs; i++)
{
if(STR_CASE_CMP(_mycodecs[i].plname, codec_inst->plname) == 0)
{
//We have found a matching codec name in the list
nameMatch = 1;
// Check if frequncy match
if (codec_inst->plfreq == _mycodecs[i].plfreq)
{
codecNumber = i;
break;
}
}
}
if(codecNumber == -1)
{
if (!nameMatch) {
// Codec name doesn't match any codec in the list
return -10;
} else {
// Error in payload frequency, doesn't match codec
return -20;
}
}
// Check the validity of payload type
if(ValidPayloadType(codec_inst->pltype) < 0)
{
// Payload type out of range
return -40;
}
// Comfort Noise is special case, packet-size & rate is not checked
if(STR_CASE_CMP(_mycodecs[codecNumber].plname, "CN") == 0)
{
mirrorID = codecNumber;
return codecNumber;
}
// RED is special case, packet-size & rate is not checked
if(STR_CASE_CMP(_mycodecs[codecNumber].plname, "red") == 0)
{
mirrorID = codecNumber;
return codecNumber;
}
// Check the validity of packet size
if(_nrOfAllowedPacSizes[codecNumber] > 0)
{
// Check that the new packet size is in the valid range.
bool pacSizeOK = false;
for(WebRtc_Word32 i=0;i< _nrOfAllowedPacSizes[codecNumber];i++)
{
if(codec_inst->pacsize == _allowedPacSizesSmpl[codecNumber][i])
{
pacSizeOK = true;
break;
}
}
if(!pacSizeOK)
{
// Packet size is out of range
return -50;
}
}
if( codec_inst->pacsize < 1)
{
// Packet size is out of range
return -50;
}
mirrorID = codecNumber;
// Check the validity of rate
if(STR_CASE_CMP("isac", codec_inst->plname) == 0)
{
if(IsISACRateValid(codec_inst->rate))
{
// Set mirrorID to iSAC WB which is only created
// once to be used both for iSAC WB and SWB, because
// they need to share struct
mirrorID = ACMCodecDB::isac;
return codecNumber;
}
else
{
// Not a valid rate
return -60;
}
}
else if(STR_CASE_CMP("ilbc", codec_inst->plname) == 0)
{
return IsILBCRateValid(codec_inst->rate, codec_inst->pacsize) ? codecNumber : -60;
}
return IsRateValid(codecNumber, codec_inst->rate) ? codecNumber : -60;
}
WebRtc_Word16
ACMCodecDB::ReceiverCodecNumber(
const CodecInst& codecInst,
WebRtc_Word16& mirrorID)
{
WebRtc_Word16 codecNumber = -1;
WebRtc_Word16 nameMatch = 0;
// Find a matching payload name and frequency in the codec list
// Need to check both since some codecs have several codec entries with
// Different frequencies (like iSAC)
for(WebRtc_Word16 i = 0; i < _noOfCodecs; i++)
{
if(STR_CASE_CMP(_mycodecs[i].plname, codecInst.plname) == 0)
{
//We have found a matching codec name in the list
nameMatch = 1;
// Check if frequency match
if (codecInst.plfreq == _mycodecs[i].plfreq)
{
codecNumber = i;
mirrorID = codecNumber;
// Check if codec is iSAC, set mirrorID to iSAC WB
// which is only created once to be used both for
// iSAC WB and SWB, because they need to share struct
if(STR_CASE_CMP(codecInst.plname, "ISAC") == 0)
{
mirrorID = ACMCodecDB::isac;
}
break;
}
}
}
if(codecNumber == -1)
{
return codecNumber;
}
return codecNumber;
}
// Return number of codecs in the database
WebRtc_Word16
ACMCodecDB::NoOfCodecs()
{
return _noOfCodecs;
}
// Return number of NetEQ decoders in the database.
// Note that the number is huigher than _moOfCodecs because some payload names
// are treated as different decoders in NetEQ, like iSAC wb and swb.
WebRtc_Word16
ACMCodecDB::NoNetEqDecoders()
{
return _noNetEqDecoders;
}
// Return the codec sampling frequency for code number "listnr" in database
WebRtc_Word32
ACMCodecDB::CodecFreq(WebRtc_Word16 listnr)
{
// Error check to se that listnr is between 0 and (_noOfCodecs - 1)
if ( listnr < 0 || listnr >= _noOfCodecs)
return -1;
return _mycodecs[listnr].plfreq;
}
// Return the codecs basic coding block size in samples
WebRtc_Word16
ACMCodecDB::BasicCodingBlock(
WebRtc_Word16 listNr)
{
// Error check to se that listnr is between 0 and (_noOfCodecs - 1)
if ( listNr < 0 || listNr >= _noOfCodecs)
return -1;
return _basicCodingBlockSmpl[listNr];
}
// Return the NetEQ decoder database
enum WebRtcNetEQDecoder*
ACMCodecDB::NetEqDecoders()
{
return _netEqDecoders;
}
// All version numbers for the codecs in the data base are listed in text.
WebRtc_Word16
ACMCodecDB::CodecsVersion(
WebRtc_Word8* version,
WebRtc_UWord32& remainingBufferInBytes,
WebRtc_UWord32& position)
{
WebRtc_UWord32 len = position;
strncpy(&version[len], _versions, remainingBufferInBytes);
position = (WebRtc_UWord32)strlen(version);
remainingBufferInBytes -= (position - len);
if(remainingBufferInBytes < _versionStringSize)
{
return -1;
}
return 0;
}
// Get mirror id. The Id is used for codecs sharing struct for settings that
// need different payload types.
WebRtc_Word16
ACMCodecDB::MirrorID(
const WebRtc_Word16 codecID)
{
if(STR_CASE_CMP(_mycodecs[codecID].plname, "isac") == 0)
{
return ACMCodecDB::isac;
}
else
{
return codecID;
}
}
ACMGenericCodec*
ACMCodecDB::CreateCodecInstance(
const CodecInst* codecInst)
{
// All we have support for right now
if(!STR_CASE_CMP(codecInst->plname, "ISAC"))
{
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
return new ACMISAC(isac);
#endif
}
else if(!STR_CASE_CMP(codecInst->plname, "PCMU"))
{
return new ACMPCMU(pcmu);
}
else if(!STR_CASE_CMP(codecInst->plname, "PCMA"))
{
return new ACMPCMA(pcma);
}
else if(!STR_CASE_CMP(codecInst->plname, "ILBC"))
{
#ifdef WEBRTC_CODEC_ILBC
return new ACMILBC(ilbc);
#endif
}
else if(!STR_CASE_CMP(codecInst->plname, "G722"))
{
#ifdef WEBRTC_CODEC_G722
return new ACMG722(g722);
#endif
}
else if(!STR_CASE_CMP(codecInst->plname, "CN"))
{
// We need to check sampling frequency
// know what codec to create.
WebRtc_Word16 codecID;
switch(codecInst->plfreq)
{
case 8000:
{
codecID = ACMCodecDB::cnNB;
break;
}
case 16000:
{
codecID = ACMCodecDB::cnWB;
break;
}
case 32000:
{
codecID = ACMCodecDB::cnSWB;
break;
}
default:
return NULL;
}
return new ACMCNG(codecID);
}
else if(!STR_CASE_CMP(codecInst->plname, "L16"))
{
#ifdef WEBRTC_CODEC_PCM16
// For this codec we need to check sampling frequency
// to know what codec to create.
WebRtc_Word16 codecID;
switch(codecInst->plfreq)
{
case 8000:
{
codecID = ACMCodecDB::pcm16b;
break;
}
case 16000:
{
codecID = ACMCodecDB::pcm16bwb;
break;
}
case 32000:
{
codecID = ACMCodecDB::pcm16bswb32;
break;
}
default:
return NULL;
}
return new ACMPCM16B(codecID);
#endif
}
else if(!STR_CASE_CMP(codecInst->plname, "telephone-event"))
{
#ifdef WEBRTC_CODEC_AVT
return new ACMDTMFPlayout(avt);
#endif
}
else if(!STR_CASE_CMP(codecInst->plname, "red"))
{
#ifdef WEBRTC_CODEC_RED
return new ACMRED(red);
#endif
}
return NULL;
}
//Here we build the complete database "_mycodecs" of our codecs
void
ACMCodecDB::initACMCodecDB()
{
if(_isInitiated)
{
return;
}
else
{
_isInitiated = true;
}
WebRtc_Word8 versionNrBuff[TEMPORARY_BUFFER_SIZE];
WebRtc_Word32 remainingSize = VERSION_SIZE;
_versions[0] = '\0';
// Init the stereo settings vector
for (int i=0; i<MAX_NR_OF_CODECS; i++)
{
_channelSupport[i] = 1;
}
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
strcpy(_mycodecs[_noOfCodecs].plname,"ISAC");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = ISACWB_DEFAULT_RATE; // Default rate
_mycodecs[_noOfCodecs].plfreq = 16000;
_mycodecs[_noOfCodecs].pltype = 103;
_mycodecs[_noOfCodecs].pacsize = ISACWB_PAC_SIZE; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 2;
_allowedPacSizesSmpl[_noOfCodecs][0] = ISACWB_PAC_SIZE; // 480 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = ISACWB_PAC_SIZE*2; // 960 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
isac=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderISAC;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
ACM_ISAC_VERSION(versionNrBuff);
strncat(_versions, "ISAC\t\t", remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, versionNrBuff, remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, "\n", remainingSize);
# if (defined(WEBRTC_CODEC_ISAC))
strcpy(_mycodecs[_noOfCodecs].plname,"ISAC");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = ISACSWB_DEFAULT_RATE; // Default rate
_mycodecs[_noOfCodecs].plfreq = 32000;
_mycodecs[_noOfCodecs].pltype = 104;
_mycodecs[_noOfCodecs].pacsize = ISACSWB_PAC_SIZE; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = ISACSWB_PAC_SIZE; // 960 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
isacswb = _noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderISACswb;
_noOfCodecs++;
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
strcpy(_mycodecs[_noOfCodecs].plname,"L16");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 128000;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = kDynamicPayloadtypes[_noPayloads++];
_mycodecs[_noOfCodecs].pacsize = 80; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 4;
_allowedPacSizesSmpl[_noOfCodecs][0] = 80; // 80 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 160; // 160 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 240; // 240 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 320; // 320 sampels equals 40 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
_channelSupport[_noOfCodecs] = 2;
pcm16b=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderPCM16B;
_noOfCodecs++;
strcpy(_mycodecs[_noOfCodecs].plname,"L16");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 256000;
_mycodecs[_noOfCodecs].plfreq = 16000;
_mycodecs[_noOfCodecs].pltype = kDynamicPayloadtypes[_noPayloads++];
_mycodecs[_noOfCodecs].pacsize = 160; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 4;
_allowedPacSizesSmpl[_noOfCodecs][0] = 160; // 160 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 320; // 320 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 480; // 480 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 640; // 640 sampels equals 40 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
_channelSupport[_noOfCodecs] = 2;
pcm16bwb=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderPCM16Bwb;
_noOfCodecs++;
strcpy(_mycodecs[_noOfCodecs].plname,"L16");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 512000;
_mycodecs[_noOfCodecs].plfreq = 32000;
_mycodecs[_noOfCodecs].pltype = kDynamicPayloadtypes[_noPayloads++];
_mycodecs[_noOfCodecs].pacsize = 320; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 2;
_allowedPacSizesSmpl[_noOfCodecs][0] = 320; // 320 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 640; // 640 sampels equals 20 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
_channelSupport[_noOfCodecs] = 2;
pcm16bswb32=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderPCM16Bswb32kHz;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, "L16\t\t1.0.0\n", remainingSize);
#endif
strcpy(_mycodecs[_noOfCodecs].plname,"PCMU");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 64000;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = 0;
_mycodecs[_noOfCodecs].pacsize = 160; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 6;
_allowedPacSizesSmpl[_noOfCodecs][0] = 80; // 80 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 160; // 160 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 240; // 240 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 320; // 320 sampels equals 40 ms
_allowedPacSizesSmpl[_noOfCodecs][4] = 400; // 400 sampels equals 50 ms
_allowedPacSizesSmpl[_noOfCodecs][5] = 480; // 480 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0; /* 0 indicates all allowed
packetsizes can be used as
basic coding block */
_channelSupport[_noOfCodecs] = 2;
pcmu=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderPCMu;
_noOfCodecs++;
strcpy(_mycodecs[_noOfCodecs].plname,"PCMA");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 64000;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = 8;
_mycodecs[_noOfCodecs].pacsize = 160; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 6;
_allowedPacSizesSmpl[_noOfCodecs][0] = 80; // 80 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 160; // 160 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 240; // 240 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 320; // 320 sampels equals 40 ms
_allowedPacSizesSmpl[_noOfCodecs][4] = 400; // 400 sampels equals 50 ms
_allowedPacSizesSmpl[_noOfCodecs][5] = 480; // 480 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0; /* 0 indicates all allowed
packetsizes can be used as
basic coding block */
_channelSupport[_noOfCodecs] = 2;
pcma=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderPCMa;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
WebRtcG711_Version(versionNrBuff, TEMPORARY_BUFFER_SIZE);
strncat(_versions, "G.711\t\t", remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, versionNrBuff, remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, "\n", remainingSize);
#ifdef WEBRTC_CODEC_ILBC
strcpy(_mycodecs[_noOfCodecs].plname,"iLBC");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 13300;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = 102;
_mycodecs[_noOfCodecs].pacsize = 240; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 4;
_allowedPacSizesSmpl[_noOfCodecs][0] = 160; // 160 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 240; // 240 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 320; // 320 sampels equals 40 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 480; // 480 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0; /* 0 indicates all allowed
packetsizes can be used as
basic coding block */
ilbc=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderILBC;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
WebRtcIlbcfix_version(versionNrBuff);
strncat(_versions, "ILBC\t\t", remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, versionNrBuff, remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, "\n", remainingSize);
#endif
#ifdef WEBRTC_CODEC_G722
strcpy(_mycodecs[_noOfCodecs].plname,"G722");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 64000;
_mycodecs[_noOfCodecs].plfreq = 16000;
_mycodecs[_noOfCodecs].pltype = 9;
_mycodecs[_noOfCodecs].pacsize = 320; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 6;
_allowedPacSizesSmpl[_noOfCodecs][0] = 160; // 160 sampels equals 10 ms
_allowedPacSizesSmpl[_noOfCodecs][1] = 320; // 320 sampels equals 20 ms
_allowedPacSizesSmpl[_noOfCodecs][2] = 480; // 480 sampels equals 30 ms
_allowedPacSizesSmpl[_noOfCodecs][3] = 640; // 640 sampels equals 40 ms
_allowedPacSizesSmpl[_noOfCodecs][4] = 800; // 480 sampels equals 50 ms
_allowedPacSizesSmpl[_noOfCodecs][5] = 960; // 640 sampels equals 60 ms
_basicCodingBlockSmpl[_noOfCodecs] = 0;
_channelSupport[_noOfCodecs] = 2;
g722=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderG722;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
WebRtcG722_Version(versionNrBuff, TEMPORARY_BUFFER_SIZE);
strncat(_versions, "G.722\t\t", remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, versionNrBuff, remainingSize);
#endif
// Comfort Noise is always included in the build, no #ifdef needed
strcpy(_mycodecs[_noOfCodecs].plname,"CN");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 0;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = 13;
_mycodecs[_noOfCodecs].pacsize = 240; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = 240; // 240 samples equals 30 ms
_basicCodingBlockSmpl[_noOfCodecs] = 240;
cnNB=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderCNG;
_noOfCodecs++;
strcpy(_mycodecs[_noOfCodecs].plname,"CN");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 0;
_mycodecs[_noOfCodecs].plfreq = 16000;
_mycodecs[_noOfCodecs].pltype = 98;
_mycodecs[_noOfCodecs].pacsize = 480; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = 480; // 480 samples equals 30 ms
_basicCodingBlockSmpl[_noOfCodecs] = 480;
cnWB=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderCNG;
_noOfCodecs++;
strcpy(_mycodecs[_noOfCodecs].plname,"CN");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 0;
_mycodecs[_noOfCodecs].plfreq = 32000;
_mycodecs[_noOfCodecs].pltype = 99;
_mycodecs[_noOfCodecs].pacsize = 960; // Default packet size
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = 960; // 960 samples equals 30 ms
_basicCodingBlockSmpl[_noOfCodecs] = 960;
cnSWB=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderCNG;
_noOfCodecs++;
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
WebRtcCng_Version(versionNrBuff);
strncat(_versions, "CNG\t\t", remainingSize);
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, versionNrBuff, remainingSize);
#ifdef WEBRTC_CODEC_AVT
strcpy(_mycodecs[_noOfCodecs].plname,"telephone-event");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].rate = 0;
_mycodecs[_noOfCodecs].pltype = 106;
_mycodecs[_noOfCodecs].pacsize = 240; // Default packet size 240ms
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = 240; // 240 samples equals 30 ms
_basicCodingBlockSmpl[_noOfCodecs] = 240;
avt=_noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderAVT;
_noOfCodecs++;
// Currently tone generation doesn't have a getVersion-function
remainingSize = (WebRtc_Word32)(VERSION_SIZE - strlen(_versions));
strncat(_versions, "Tone Generation\t1.0.0\n", remainingSize);
#endif
#ifdef WEBRTC_CODEC_RED
strcpy(_mycodecs[_noOfCodecs].plname,"red");
_mycodecs[_noOfCodecs].channels = 1;
_mycodecs[_noOfCodecs].rate = 0;
_mycodecs[_noOfCodecs].plfreq = 8000;
_mycodecs[_noOfCodecs].pltype = 127;
_mycodecs[_noOfCodecs].pacsize = 0;
_nrOfAllowedPacSizes[_noOfCodecs] = 1;
_allowedPacSizesSmpl[_noOfCodecs][0] = 0;
_basicCodingBlockSmpl[_noOfCodecs] = 0;
red = _noOfCodecs;
_netEqDecoders[_noNetEqDecoders++] = kDecoderRED;
_noOfCodecs++;
#endif
_versionStringSize = (WebRtc_UWord32)strlen(_versions);
}
// Check if the bitrate is valid for the codec
bool
ACMCodecDB::IsRateValid(
const WebRtc_Word16 listNr,
const WebRtc_Word32 rate)
{
if(_mycodecs[listNr].rate == rate)
{
return true;
}
else
{
return false;
}
}
// Check if the bitrate is valid for iSAC
bool
ACMCodecDB::IsISACRateValid(
#if (!defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX))
const WebRtc_Word32 /* rate */)
{
return false;
#else
const WebRtc_Word32 rate)
{
if((rate == -1) ||
((rate <= 56000) && (rate >= 10000)))
{
return true;
}
else
{
return false;
}
#endif
}
// Check if the bitrate is valid for iLBC
bool
ACMCodecDB::IsILBCRateValid(
#ifndef WEBRTC_CODEC_ILBC
const WebRtc_Word32 /* rate */,
const WebRtc_Word16 /* frameSizeSamples */)
{
return false;
#else
const WebRtc_Word32 rate,
const WebRtc_Word16 frameSizeSamples)
{
if(((frameSizeSamples == 240) || (frameSizeSamples == 480)) &&
(rate == 13300))
{
return true;
}
else if(((frameSizeSamples == 160) || (frameSizeSamples == 320)) &&
(rate == 15200))
{
return true;
}
else
{
return false;
}
#endif
}
// Check if the payload type is valid
WebRtc_Word16
ACMCodecDB::ValidPayloadType(
const int payloadType)
{
if((payloadType < 0) || (payloadType > 127))
{
return -1;
}
return 0;
}
} // namespace webrtc