| /* |
| * 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 |