git-svn-id: http://webrtc.googlecode.com/svn/trunk@4 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
		
							
								
								
									
										737
									
								
								modules/audio_coding/NetEQ/main/source/codec_db.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										737
									
								
								modules/audio_coding/NetEQ/main/source/codec_db.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,737 @@ | ||||
| /* | ||||
|  *  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. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Implementation of the codec database. | ||||
|  */ | ||||
|  | ||||
| #include "codec_db.h" | ||||
|  | ||||
| #include <string.h> /* to define NULL */ | ||||
|  | ||||
| #include "signal_processing_library.h" | ||||
|  | ||||
| #include "neteq_error_codes.h" | ||||
|  | ||||
| /* | ||||
|  * Resets the codec database. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbReset(CodecDbInst_t *inst) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     WebRtcSpl_MemSetW16((WebRtc_Word16*) inst, 0, | ||||
|         sizeof(CodecDbInst_t) / sizeof(WebRtc_Word16)); | ||||
|  | ||||
|     for (i = 0; i < NUM_TOTAL_CODECS; i++) | ||||
|     { | ||||
|         inst->position[i] = -1; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < NUM_CODECS; i++) | ||||
|     { | ||||
|         inst->payloadType[i] = -1; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < NUM_CNG_CODECS; i++) | ||||
|     { | ||||
|         inst->CNGpayloadType[i] = -1; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Adds a new codec to the database. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, | ||||
|                       WebRtc_Word16 payloadType, FuncDecode funcDecode, | ||||
|                       FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC, | ||||
|                       FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt, | ||||
|                       FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch, | ||||
|                       FuncUpdBWEst funcUpdBWEst, FuncGetErrorCode funcGetErrorCode, | ||||
|                       void* codec_state, WebRtc_UWord16 codec_fs) | ||||
| { | ||||
|  | ||||
|     int temp; | ||||
|     int insertCNGcodec = 0, overwriteCNGcodec = 0, CNGpos = -1; | ||||
|  | ||||
| #ifndef NETEQ_RED_CODEC | ||||
|     if (codec == kDecoderRED) | ||||
|     { | ||||
|         return CODEC_DB_UNSUPPORTED_CODEC; | ||||
|     } | ||||
| #endif | ||||
|     if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec | ||||
|         >= (int) kDecoderReservedEnd)) | ||||
|     { | ||||
|         return CODEC_DB_UNSUPPORTED_CODEC; | ||||
|     } | ||||
|  | ||||
|     if ((codec_fs != 8000) | ||||
| #ifdef NETEQ_WIDEBAND | ||||
|     &&(codec_fs!=16000) | ||||
| #endif | ||||
| #ifdef NETEQ_32KHZ_WIDEBAND | ||||
|     &&(codec_fs!=32000) | ||||
| #endif | ||||
| #ifdef NETEQ_48KHZ_WIDEBAND | ||||
|     &&(codec_fs!=48000) | ||||
| #endif | ||||
|     ) | ||||
|     { | ||||
|         return CODEC_DB_UNSUPPORTED_FS; | ||||
|     } | ||||
|  | ||||
|     /* Ensure that the codec type is supported */ | ||||
|     switch (codec) | ||||
|     { | ||||
| #ifdef NETEQ_PCM16B_CODEC | ||||
|         case kDecoderPCM16B : | ||||
| #endif | ||||
| #ifdef NETEQ_G711_CODEC | ||||
|         case kDecoderPCMu : | ||||
|         case kDecoderPCMa : | ||||
| #endif | ||||
| #ifdef NETEQ_ILBC_CODEC | ||||
|         case kDecoderILBC : | ||||
| #endif | ||||
| #ifdef NETEQ_ISAC_CODEC | ||||
|         case kDecoderISAC : | ||||
| #endif | ||||
| #ifdef NETEQ_ISAC_SWB_CODEC | ||||
|         case kDecoderISACswb : | ||||
| #endif | ||||
| #ifdef NETEQ_G722_CODEC | ||||
|         case kDecoderG722 : | ||||
| #endif | ||||
| #ifdef NETEQ_WIDEBAND | ||||
|         case kDecoderPCM16Bwb : | ||||
| #endif | ||||
| #ifdef NETEQ_32KHZ_WIDEBAND | ||||
|         case kDecoderPCM16Bswb32kHz : | ||||
| #endif | ||||
| #ifdef NETEQ_CNG_CODEC | ||||
|         case kDecoderCNG : | ||||
| #endif | ||||
| #ifdef NETEQ_ATEVENT_DECODE | ||||
|         case kDecoderAVT : | ||||
| #endif | ||||
| #ifdef NETEQ_RED_CODEC | ||||
|         case kDecoderRED : | ||||
| #endif | ||||
| #ifdef NETEQ_48KHZ_WIDEBAND | ||||
|         case kDecoderPCM16Bswb48kHz : | ||||
| #endif | ||||
| #ifdef NETEQ_ARBITRARY_CODEC | ||||
|         case kDecoderArbitrary: | ||||
| #endif | ||||
| #ifdef NETEQ_G729_CODEC | ||||
|         case kDecoderG729: | ||||
| #endif | ||||
| #ifdef NETEQ_G729_1_CODEC | ||||
|         case kDecoderG729_1 : | ||||
| #endif | ||||
| #ifdef NETEQ_G726_CODEC | ||||
|         case kDecoderG726_16 : | ||||
|         case kDecoderG726_24 : | ||||
|         case kDecoderG726_32 : | ||||
|         case kDecoderG726_40 : | ||||
| #endif | ||||
| #ifdef NETEQ_G722_1_CODEC | ||||
|         case kDecoderG722_1_16 : | ||||
|         case kDecoderG722_1_24 : | ||||
|         case kDecoderG722_1_32 : | ||||
| #endif | ||||
| #ifdef NETEQ_G722_1C_CODEC | ||||
|         case kDecoderG722_1C_24 : | ||||
|         case kDecoderG722_1C_32 : | ||||
|         case kDecoderG722_1C_48 : | ||||
| #endif | ||||
| #ifdef NETEQ_SPEEX_CODEC | ||||
|         case kDecoderSPEEX_8 : | ||||
|         case kDecoderSPEEX_16 : | ||||
| #endif | ||||
| #ifdef NETEQ_GSMFR_CODEC | ||||
|         case kDecoderGSMFR : | ||||
| #endif | ||||
| #ifdef NETEQ_AMR_CODEC | ||||
|         case kDecoderAMR : | ||||
| #endif | ||||
| #ifdef NETEQ_AMRWB_CODEC | ||||
|         case kDecoderAMRWB : | ||||
| #endif | ||||
|         { | ||||
|             /* If we end up here, the inserted codec is supported => Do nothing */ | ||||
|             break; | ||||
|         } | ||||
|     default: | ||||
|     { | ||||
|         /* If we get to this point, the inserted codec is not supported */ | ||||
|         return CODEC_DB_UNSUPPORTED_CODEC; | ||||
|     } | ||||
|     } | ||||
|  | ||||
|     /* Check to see if payload type is taken */ | ||||
|     if (WebRtcNetEQ_DbGetCodec(inst, payloadType) > 0) | ||||
|     { | ||||
|         return CODEC_DB_PAYLOAD_TAKEN; | ||||
|     } | ||||
|  | ||||
|     /* Special case for CNG codecs */ | ||||
|     if (codec == kDecoderCNG) | ||||
|     { | ||||
|         /* check if this is first CNG codec to be registered */ | ||||
|         if (WebRtcNetEQ_DbGetPayload(inst, codec) == CODEC_DB_NOT_EXIST2) | ||||
|         { | ||||
|             /* no other CNG codec found */ | ||||
|             insertCNGcodec = 1; | ||||
|         } | ||||
|  | ||||
|         /* find the appropriate insert position in CNG payload vector */ | ||||
|         switch (codec_fs) | ||||
|         { | ||||
| #ifdef NETEQ_WIDEBAND | ||||
|             case 16000: | ||||
|             CNGpos = 1; | ||||
|             break; | ||||
| #endif | ||||
| #ifdef NETEQ_32KHZ_WIDEBAND | ||||
|             case 32000: | ||||
|             CNGpos = 2; | ||||
|             break; | ||||
| #endif | ||||
| #ifdef NETEQ_48KHZ_WIDEBAND | ||||
|             case 48000: | ||||
|             CNGpos = 3; | ||||
|             break; | ||||
| #endif | ||||
|             default: /* 8000 Hz case */ | ||||
|                 CNGpos = 0; | ||||
|                 /* | ||||
|                  * The 8 kHz CNG payload type is the one associated with the regular codec DB | ||||
|                  * should override any other setting. | ||||
|                  * Overwrite if this isn't the first CNG | ||||
|                  */ | ||||
|                 overwriteCNGcodec = !insertCNGcodec; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         /* insert CNG payload type */ | ||||
|         inst->CNGpayloadType[CNGpos] = payloadType; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     if ((codec != kDecoderCNG) || (insertCNGcodec == 1) || (overwriteCNGcodec == 1)) | ||||
|     { | ||||
|         /* Check if we have reached the maximum numbers of simultaneous codecs */ | ||||
|         if (inst->nrOfCodecs == NUM_CODECS) return CODEC_DB_FULL; | ||||
|  | ||||
|         /* Check that codec has not already been initialized to DB => | ||||
|          remove it and reinitialize according to new spec */ | ||||
|         if ((inst->position[codec] != -1) && (overwriteCNGcodec != 1)) | ||||
|         { /* if registering multiple CNG codecs, don't remove, just overwrite */ | ||||
|             WebRtcNetEQ_DbRemove(inst, codec); | ||||
|         } | ||||
|  | ||||
|         if (overwriteCNGcodec == 1) | ||||
|         { | ||||
|             temp = inst->position[codec]; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             temp = inst->nrOfCodecs; /* Store this codecs position */ | ||||
|             inst->position[codec] = temp; | ||||
|             inst->nrOfCodecs++; | ||||
|         } | ||||
|  | ||||
|         inst->payloadType[temp] = payloadType; | ||||
|  | ||||
|         /* Copy to database */ | ||||
|         inst->codec_state[temp] = codec_state; | ||||
|         inst->funcDecode[temp] = funcDecode; | ||||
|         inst->funcDecodeRCU[temp] = funcDecodeRCU; | ||||
|         inst->funcAddLatePkt[temp] = funcAddLatePkt; | ||||
|         inst->funcDecodeInit[temp] = funcDecodeInit; | ||||
|         inst->funcDecodePLC[temp] = funcDecodePLC; | ||||
|         inst->funcGetMDinfo[temp] = funcGetMDinfo; | ||||
|         inst->funcGetPitch[temp] = funcGetPitch; | ||||
|         inst->funcUpdBWEst[temp] = funcUpdBWEst; | ||||
|         inst->funcGetErrorCode[temp] = funcGetErrorCode; | ||||
|         inst->codec_fs[temp] = codec_fs; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Removes a codec from the database. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec) | ||||
| { | ||||
|     int i; | ||||
|     int pos = -1; | ||||
|  | ||||
| #ifndef NETEQ_RED_CODEC | ||||
|     if (codec == kDecoderRED) | ||||
|     { | ||||
|         return CODEC_DB_UNSUPPORTED_CODEC; | ||||
|     } | ||||
| #endif | ||||
|     if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec | ||||
|         >= (int) kDecoderReservedEnd)) | ||||
|     { | ||||
|         return CODEC_DB_UNSUPPORTED_CODEC; | ||||
|     } | ||||
|  | ||||
|     pos = inst->position[codec]; | ||||
|     if (pos == -1) | ||||
|     { | ||||
|         return CODEC_DB_NOT_EXIST4; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         /* Remove this codec */ | ||||
|         inst->position[codec] = -1; | ||||
|         for (i = pos; i < (inst->nrOfCodecs - 1); i++) | ||||
|         { | ||||
|             inst->payloadType[i] = inst->payloadType[i + 1]; | ||||
|             inst->codec_state[i] = inst->codec_state[i + 1]; | ||||
|             inst->funcDecode[i] = inst->funcDecode[i + 1]; | ||||
|             inst->funcDecodeRCU[i] = inst->funcDecodeRCU[i + 1]; | ||||
|             inst->funcAddLatePkt[i] = inst->funcAddLatePkt[i + 1]; | ||||
|             inst->funcDecodeInit[i] = inst->funcDecodeInit[i + 1]; | ||||
|             inst->funcDecodePLC[i] = inst->funcDecodePLC[i + 1]; | ||||
|             inst->funcGetMDinfo[i] = inst->funcGetMDinfo[i + 1]; | ||||
|             inst->funcGetPitch[i] = inst->funcGetPitch[i + 1]; | ||||
|             inst->funcUpdBWEst[i] = inst->funcUpdBWEst[i + 1]; | ||||
|             inst->funcGetErrorCode[i] = inst->funcGetErrorCode[i + 1]; | ||||
|             inst->codec_fs[i] = inst->codec_fs[i + 1]; | ||||
|         } | ||||
|         inst->payloadType[i] = -1; | ||||
|         inst->codec_state[i] = NULL; | ||||
|         inst->funcDecode[i] = NULL; | ||||
|         inst->funcDecodeRCU[i] = NULL; | ||||
|         inst->funcAddLatePkt[i] = NULL; | ||||
|         inst->funcDecodeInit[i] = NULL; | ||||
|         inst->funcDecodePLC[i] = NULL; | ||||
|         inst->funcGetMDinfo[i] = NULL; | ||||
|         inst->funcGetPitch[i] = NULL; | ||||
|         inst->funcUpdBWEst[i] = NULL; | ||||
|         inst->funcGetErrorCode[i] = NULL; | ||||
|         inst->codec_fs[i] = 0; | ||||
|         /* Move down all the codecs above this one */ | ||||
|         for (i = 0; i < NUM_TOTAL_CODECS; i++) | ||||
|         { | ||||
|             if (inst->position[i] >= pos) | ||||
|             { | ||||
|                 inst->position[i] = inst->position[i] - 1; | ||||
|             } | ||||
|         } | ||||
|         inst->nrOfCodecs--; | ||||
|  | ||||
|         if (codec == kDecoderCNG) | ||||
|         { | ||||
|             /* also remove all registered CNG payload types */ | ||||
|             for (i = 0; i < NUM_CNG_CODECS; i++) | ||||
|             { | ||||
|                 inst->CNGpayloadType[i] = -1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Get the decoder function pointers for a codec. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, | ||||
|                           CodecFuncInst_t *ptr_inst) | ||||
| { | ||||
|  | ||||
|     int pos = inst->position[codec]; | ||||
|     if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec | ||||
|         > NUM_TOTAL_CODECS)) | ||||
|     { | ||||
|         /* ERROR */ | ||||
|         pos = -1; | ||||
|     } | ||||
|     if (pos >= 0) | ||||
|     { | ||||
|         ptr_inst->codec_state = inst->codec_state[pos]; | ||||
|         ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos]; | ||||
|         ptr_inst->funcDecode = inst->funcDecode[pos]; | ||||
|         ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos]; | ||||
|         ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos]; | ||||
|         ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos]; | ||||
|         ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos]; | ||||
|         ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos]; | ||||
|         ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos]; | ||||
|         ptr_inst->codec_fs = inst->codec_fs[pos]; | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         WebRtcSpl_MemSetW16((WebRtc_Word16*) ptr_inst, 0, | ||||
|             sizeof(CodecFuncInst_t) / sizeof(WebRtc_Word16)); | ||||
|         return CODEC_DB_NOT_EXIST1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns payload number given a codec identifier. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID) | ||||
| { | ||||
|     if (inst->position[codecID] == -1) | ||||
|         return CODEC_DB_NOT_EXIST2; | ||||
|     else | ||||
|         return (inst->payloadType[inst->position[codecID]]); | ||||
|  | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns codec identifier given a payload number. | ||||
|  * Returns -1 if the payload type does not exist. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbGetCodec(CodecDbInst_t *inst, int payloadType) | ||||
| { | ||||
|     int i, pos; | ||||
|  | ||||
|     for (i = 0; i < NUM_TOTAL_CODECS; i++) | ||||
|     { | ||||
|         pos = inst->position[i]; | ||||
|         if (pos != -1) | ||||
|         { | ||||
|             if (inst->payloadType[pos] == payloadType) return i; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* did not find payload type */ | ||||
|     /* check if it's a CNG codec */ | ||||
|     if (WebRtcNetEQ_DbIsCNGPayload(inst, payloadType)) | ||||
|     { | ||||
|         return kDecoderCNG; | ||||
|     } | ||||
|  | ||||
|     /* found no match */ | ||||
|     return CODEC_DB_NOT_EXIST3; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Extracts the Payload Split information of the codec with the specified payloadType. | ||||
|  */ | ||||
|  | ||||
| int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID, | ||||
|                                int codedsize) | ||||
| { | ||||
|  | ||||
|     switch (codecID) | ||||
|     { | ||||
| #ifdef NETEQ_ISAC_CODEC | ||||
|         case kDecoderISAC: | ||||
| #endif | ||||
| #ifdef NETEQ_ISAC_SWB_CODEC | ||||
|         case kDecoderISACswb: | ||||
| #endif | ||||
| #ifdef NETEQ_ARBITRARY_CODEC | ||||
|         case kDecoderArbitrary: | ||||
| #endif | ||||
| #ifdef NETEQ_AMR_CODEC | ||||
|         case kDecoderAMR: | ||||
| #endif | ||||
| #ifdef NETEQ_AMRWB_CODEC | ||||
|         case kDecoderAMRWB: | ||||
| #endif | ||||
| #ifdef NETEQ_G726_CODEC | ||||
|             /* Treat G726 as non-splittable to simplify the implementation */ | ||||
|         case kDecoderG726_16: | ||||
|         case kDecoderG726_24: | ||||
|         case kDecoderG726_32: | ||||
|         case kDecoderG726_40: | ||||
| #endif | ||||
| #ifdef NETEQ_SPEEX_CODEC | ||||
|         case kDecoderSPEEX_8: | ||||
|         case kDecoderSPEEX_16: | ||||
| #endif | ||||
| #ifdef NETEQ_G729_1_CODEC | ||||
|         case kDecoderG729_1: | ||||
| #endif | ||||
|         { | ||||
|             /* These codecs' payloads are not splittable */ | ||||
|             inst->deltaBytes = NO_SPLIT; | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|             /* | ||||
|              * Sample based coders are a special case. | ||||
|              * In this case, deltaTime signals the number of bytes per timestamp unit times 2 | ||||
|              * in log2 domain. | ||||
|              */ | ||||
| #if (defined NETEQ_G711_CODEC) | ||||
|         case kDecoderPCMu: | ||||
|         case kDecoderPCMa: | ||||
|         { | ||||
|             inst->deltaBytes = -12; | ||||
|             inst->deltaTime = 1; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #if (defined NETEQ_G722_CODEC) | ||||
|         case kDecoderG722: | ||||
|         { | ||||
|             inst->deltaBytes = -14; | ||||
|             inst->deltaTime = 0; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #if (defined NETEQ_PCM16B_CODEC) | ||||
|         case kDecoderPCM16B: | ||||
|         { | ||||
|             inst->deltaBytes = -12; | ||||
|             inst->deltaTime = 2; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND)) | ||||
|         case kDecoderPCM16Bwb: | ||||
|         { | ||||
|             inst->deltaBytes = -14; | ||||
|             inst->deltaTime = 2; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND)) | ||||
|         case kDecoderPCM16Bswb32kHz: | ||||
|         { | ||||
|             inst->deltaBytes = -18; | ||||
|             inst->deltaTime = 2; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_48KHZ_WIDEBAND)) | ||||
|         case kDecoderPCM16Bswb48kHz: | ||||
|         { | ||||
|             inst->deltaBytes = -22; | ||||
|             inst->deltaTime = 2; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|             /* Splittable payloads */ | ||||
| #ifdef NETEQ_G722_1_CODEC | ||||
|         case kDecoderG722_1_16: | ||||
|         { | ||||
|             inst->deltaBytes = 40; | ||||
|             inst->deltaTime = 320; | ||||
|             return 0; | ||||
|         } | ||||
|         case kDecoderG722_1_24: | ||||
|         { | ||||
|             inst->deltaBytes = 60; | ||||
|             inst->deltaTime = 320; | ||||
|             return 0; | ||||
|         } | ||||
|         case kDecoderG722_1_32: | ||||
|         { | ||||
|             inst->deltaBytes = 80; | ||||
|             inst->deltaTime = 320; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #ifdef NETEQ_G722_1C_CODEC | ||||
|         case kDecoderG722_1C_24: | ||||
|         { | ||||
|             inst->deltaBytes = 60; | ||||
|             inst->deltaTime = 640; | ||||
|             return 0; | ||||
|         } | ||||
|         case kDecoderG722_1C_32: | ||||
|         { | ||||
|             inst->deltaBytes = 80; | ||||
|             inst->deltaTime = 640; | ||||
|             return 0; | ||||
|         } | ||||
|         case kDecoderG722_1C_48: | ||||
|         { | ||||
|             inst->deltaBytes = 120; | ||||
|             inst->deltaTime = 640; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #ifdef NETEQ_G729_CODEC | ||||
|         case kDecoderG729: | ||||
|         { | ||||
|             inst->deltaBytes = 10; | ||||
|             inst->deltaTime = 80; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #ifdef NETEQ_ILBC_CODEC | ||||
|         case kDecoderILBC: | ||||
|         { | ||||
|             /* Check for splitting of iLBC packets. | ||||
|              * If payload size is a multiple of 50 bytes it should be split into 30ms frames. | ||||
|              * If payload size is a multiple of 38 bytes it should be split into 20ms frames. | ||||
|              * Least common multiplier between 38 and 50 is 950, so the payload size must be less than | ||||
|              * 950 bytes in order to resolve the frames unambiguously. | ||||
|              * Currently max 12 frames in one bundle. | ||||
|              */ | ||||
|             switch (codedsize) | ||||
|             { | ||||
|                 case 50: | ||||
|                 case 100: | ||||
|                 case 150: | ||||
|                 case 200: | ||||
|                 case 250: | ||||
|                 case 300: | ||||
|                 case 350: | ||||
|                 case 400: | ||||
|                 case 450: | ||||
|                 case 500: | ||||
|                 case 550: | ||||
|                 case 600: | ||||
|                 { | ||||
|                     inst->deltaBytes = 50; | ||||
|                     inst->deltaTime = 240; | ||||
|                     break; | ||||
|                 } | ||||
|                 case 38: | ||||
|                 case 76: | ||||
|                 case 114: | ||||
|                 case 152: | ||||
|                 case 190: | ||||
|                 case 228: | ||||
|                 case 266: | ||||
|                 case 304: | ||||
|                 case 342: | ||||
|                 case 380: | ||||
|                 case 418: | ||||
|                 case 456: | ||||
|                 { | ||||
|                     inst->deltaBytes = 38; | ||||
|                     inst->deltaTime = 160; | ||||
|                     break; | ||||
|                 } | ||||
|                 default: | ||||
|                 { | ||||
|                     return AMBIGUOUS_ILBC_FRAME_SIZE; /* Something not supported... */ | ||||
|                 } | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
| #ifdef NETEQ_GSMFR_CODEC | ||||
|         case kDecoderGSMFR: | ||||
|         { | ||||
|             inst->deltaBytes = 33; | ||||
|             inst->deltaTime = 160; | ||||
|             return 0; | ||||
|         } | ||||
| #endif | ||||
|         default: | ||||
|         { /*Unknown codec */ | ||||
|             inst->deltaBytes = NO_SPLIT; | ||||
|             return CODEC_DB_UNKNOWN_CODEC; | ||||
|         } | ||||
|     } /* end of switch */ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns 1 if codec is multiple description, 0 otherwise. | ||||
|  * NOTE: This function is a stub, since there currently are no MD codecs. | ||||
|  */ | ||||
| int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID) | ||||
| { | ||||
|     if (0) /* Add test for MD codecs here */ | ||||
|         return 1; | ||||
|     else | ||||
|         return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns 1 if payload type is registered as a CNG codec, 0 otherwise | ||||
|  */ | ||||
| int WebRtcNetEQ_DbIsCNGPayload(CodecDbInst_t *inst, int payloadType) | ||||
| { | ||||
| #ifdef NETEQ_CNG_CODEC | ||||
|     int i; | ||||
|  | ||||
|     for(i=0; i<NUM_CNG_CODECS; i++) | ||||
|     { | ||||
|         if( (inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType) ) | ||||
|         { | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     return 0; | ||||
|  | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Return the sample rate for the codec with the given payload type, 0 if error | ||||
|  */ | ||||
| WebRtc_UWord16 WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType) | ||||
| { | ||||
|     int i; | ||||
|     CodecFuncInst_t codecInst; | ||||
|  | ||||
|     /* Sanity */ | ||||
|     if (inst == NULL) | ||||
|     { | ||||
|         /* return 0 Hz */ | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* Check among CNG payloads */ | ||||
|     for (i = 0; i < NUM_CNG_CODECS; i++) | ||||
|     { | ||||
|         if ((inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType)) | ||||
|         { | ||||
|             switch (i) | ||||
|             { | ||||
|                 case 1: | ||||
|                     return 16000; | ||||
|                 case 2: | ||||
|                     return 32000; | ||||
|                 case 3: | ||||
|                     return 48000; | ||||
|                 default: | ||||
|                     return 8000; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* Not a CNG payload, check the other payloads */ | ||||
|     i = WebRtcNetEQ_DbGetCodec(inst, payloadType); | ||||
|     if (i >= 0) | ||||
|     { | ||||
|         if (WebRtcNetEQ_DbGetPtrs(inst, (enum WebRtcNetEQDecoder) i, &codecInst) != 0) | ||||
|         { | ||||
|             /* Unexpected error, return 0 Hz */ | ||||
|             return 0; | ||||
|         } | ||||
|         return codecInst.codec_fs; | ||||
|     } | ||||
|  | ||||
|     /* If we end up here, we got an error, return 0 Hz */ | ||||
|     return 0; | ||||
|  | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 niklase@google.com
					niklase@google.com