diff --git a/webrtc/modules/audio_coding/codecs/g711/g711_interface.c b/webrtc/modules/audio_coding/codecs/g711/g711_interface.c index a49abdbe8f..c809eacc6a 100644 --- a/webrtc/modules/audio_coding/codecs/g711/g711_interface.c +++ b/webrtc/modules/audio_coding/codecs/g711/g711_interface.c @@ -164,6 +164,16 @@ WebRtc_Word16 WebRtcG711_DecodeU(void *state, return (len); } +int WebRtcG711_DurationEst(void* state, + const uint8_t* payload, + int payload_length_bytes) { + (void)state; + (void)payload; + /* G.711 is one byte per sample, so we can just return the number of + bytes. */ + return payload_length_bytes; +} + WebRtc_Word16 WebRtcG711_Version(char* version, WebRtc_Word16 lenBytes) { strncpy(version, "2.0.0", lenBytes); diff --git a/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h b/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h index 25a9903331..4c7f41b3e7 100644 --- a/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h +++ b/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h @@ -123,6 +123,27 @@ WebRtc_Word16 WebRtcG711_DecodeU(void *state, WebRtc_Word16 *decoded, WebRtc_Word16 *speechType); + +/**************************************************************************** + * WebRtcG711_DurationEst(...) + * + * This function estimates the duration of a G711 packet in samples. + * + * Input: + * - state : Dummy state to make this codec look more like + * other codecs + * - payload : Encoded data + * - payloadLengthBytes : Bytes in encoded vector + * + * Return value : The duration of the packet in samples, which is + * just payload_length_bytes, since G.711 uses one + * byte per sample. + */ + +int WebRtcG711_DurationEst(void* state, + const uint8_t* payload, + int payload_length_bytes); + /********************************************************************** * WebRtcG711_Version(...) * diff --git a/webrtc/modules/audio_coding/neteq/codec_db.c b/webrtc/modules/audio_coding/neteq/codec_db.c index b69b886fd3..fd59886990 100644 --- a/webrtc/modules/audio_coding/neteq/codec_db.c +++ b/webrtc/modules/audio_coding/neteq/codec_db.c @@ -58,8 +58,9 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC, FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt, FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch, - FuncUpdBWEst funcUpdBWEst, FuncGetErrorCode funcGetErrorCode, - void* codec_state, WebRtc_UWord16 codec_fs) + FuncUpdBWEst funcUpdBWEst, FuncDurationEst funcDurationEst, + FuncGetErrorCode funcGetErrorCode, void* codec_state, + WebRtc_UWord16 codec_fs) { int temp; @@ -280,6 +281,7 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, inst->funcGetMDinfo[temp] = funcGetMDinfo; inst->funcGetPitch[temp] = funcGetPitch; inst->funcUpdBWEst[temp] = funcUpdBWEst; + inst->funcDurationEst[temp] = funcDurationEst; inst->funcGetErrorCode[temp] = funcGetErrorCode; inst->codec_fs[temp] = codec_fs; @@ -422,7 +424,7 @@ int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecI * Returns -1 if the payload type does not exist. */ -int WebRtcNetEQ_DbGetCodec(CodecDbInst_t *inst, int payloadType) +int WebRtcNetEQ_DbGetCodec(const CodecDbInst_t *inst, int payloadType) { int i, pos; @@ -694,7 +696,7 @@ int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID) /* * Returns 1 if payload type is registered as a CNG codec, 0 otherwise */ -int WebRtcNetEQ_DbIsCNGPayload(CodecDbInst_t *inst, int payloadType) +int WebRtcNetEQ_DbIsCNGPayload(const CodecDbInst_t *inst, int payloadType) { #ifdef NETEQ_CNG_CODEC int i; diff --git a/webrtc/modules/audio_coding/neteq/codec_db.h b/webrtc/modules/audio_coding/neteq/codec_db.h index 7f429807c5..102dec847d 100644 --- a/webrtc/modules/audio_coding/neteq/codec_db.h +++ b/webrtc/modules/audio_coding/neteq/codec_db.h @@ -46,6 +46,7 @@ typedef struct FuncGetMDinfo funcGetMDinfo[NUM_CODECS]; FuncGetPitchInfo funcGetPitch[NUM_CODECS]; FuncUpdBWEst funcUpdBWEst[NUM_CODECS]; + FuncDurationEst funcDurationEst[NUM_CODECS]; FuncGetErrorCode funcGetErrorCode[NUM_CODECS]; void * codec_state[NUM_CODECS]; WebRtc_UWord16 codec_fs[NUM_CODECS]; @@ -74,8 +75,9 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC, FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt, FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch, - FuncUpdBWEst funcUpdBWEst, FuncGetErrorCode funcGetErrorCode, - void* codec_state, WebRtc_UWord16 codec_fs); + FuncUpdBWEst funcUpdBWEst, FuncDurationEst funcDurationEst, + FuncGetErrorCode funcGetErrorCode, void* codec_state, + WebRtc_UWord16 codec_fs); /* * Removes a codec from the database. @@ -98,7 +100,7 @@ int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecI * Returns codec identifier given a payload number. */ -int WebRtcNetEQ_DbGetCodec(CodecDbInst_t *inst, int payloadType); +int WebRtcNetEQ_DbGetCodec(const CodecDbInst_t *inst, int payloadType); /* * Extracts the Payload Split information of the codec with the specified payloadType. @@ -115,7 +117,7 @@ int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID); /* * Returns 1 if payload type is registered as a CNG codec, 0 otherwise. */ -int WebRtcNetEQ_DbIsCNGPayload(CodecDbInst_t *inst, int payloadType); +int WebRtcNetEQ_DbIsCNGPayload(const CodecDbInst_t *inst, int payloadType); /* * Return the sample rate for the codec with the given payload type, 0 if error. diff --git a/webrtc/modules/audio_coding/neteq/codec_db_defines.h b/webrtc/modules/audio_coding/neteq/codec_db_defines.h index 9b78b862fd..ffe1e85499 100644 --- a/webrtc/modules/audio_coding/neteq/codec_db_defines.h +++ b/webrtc/modules/audio_coding/neteq/codec_db_defines.h @@ -63,6 +63,13 @@ typedef WebRtc_Word16 (*FuncUpdBWEst)(void* state, const WebRtc_UWord16 *encoded WebRtc_UWord16 rtp_seq_number, WebRtc_UWord32 send_ts, WebRtc_UWord32 arr_ts); +/* + * Pointer to the frame size estimate function. + * Returns the estimated number of samples in the packet. + */ +typedef int (*FuncDurationEst)(void* state, const uint8_t* payload, + int payload_length_bytes); + /* * Pointer to error code function */ @@ -78,6 +85,7 @@ typedef struct CodecFuncInst_t_ FuncAddLatePkt funcAddLatePkt; FuncGetMDinfo funcGetMDinfo; FuncUpdBWEst funcUpdBWEst; /* Currently in use for the ISAC family (without LC) only*/ + FuncDurationEst funcDurationEst; FuncGetErrorCode funcGetErrorCode; void * codec_state; WebRtc_UWord16 codec_fs; diff --git a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h index 83326cc578..5af201e04b 100644 --- a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h +++ b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h @@ -127,6 +127,8 @@ typedef WebRtc_Word16 (*WebRtcNetEQ_FuncUpdBWEst)(void* state, const WebRtc_UWor WebRtc_UWord16 rtp_seq_number, WebRtc_UWord32 send_ts, WebRtc_UWord32 arr_ts); +typedef int (*WebRtcNetEQ_FuncDurationEst)(void* state, const uint8_t* payload, + int payload_length_bytes); typedef WebRtc_Word16 (*WebRtcNetEQ_FuncGetErrorCode)(void* state); /********************************************************** @@ -145,6 +147,7 @@ typedef struct WebRtcNetEQ_FuncGetMDinfo funcGetMDinfo; WebRtcNetEQ_FuncGetPitchInfo funcGetPitch; WebRtcNetEQ_FuncUpdBWEst funcUpdBWEst; + WebRtcNetEQ_FuncDurationEst funcDurationEst; WebRtcNetEQ_FuncGetErrorCode funcGetErrorCode; void* codec_state; WebRtc_UWord16 codec_fs; diff --git a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h index 519eb71846..325fcc4bf3 100644 --- a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h +++ b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h @@ -39,6 +39,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=WebRtcG711_DurationEst; \ inst.funcGetErrorCode=NULL; #define SET_PCMA_FUNCTIONS(inst) \ @@ -50,6 +51,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=WebRtcG711_DurationEst; \ inst.funcGetErrorCode=NULL; #define SET_ILBC_FUNCTIONS(inst) \ @@ -61,6 +63,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_ISAC_FUNCTIONS(inst) \ @@ -72,6 +75,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsac_UpdateBwEstimate; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; #define SET_ISACfix_FUNCTIONS(inst) \ @@ -83,6 +87,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsacfix_UpdateBwEstimate; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsacfix_GetErrorCode; #define SET_ISACSWB_FUNCTIONS(inst) \ @@ -94,6 +99,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsac_UpdateBwEstimate; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; #define SET_G729_FUNCTIONS(inst) \ @@ -105,6 +111,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G729_1_FUNCTIONS(inst) \ @@ -116,6 +123,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcG7291_DecodeBwe; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_PCM16B_FUNCTIONS(inst) \ @@ -127,6 +135,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_PCM16B_WB_FUNCTIONS(inst) \ @@ -138,6 +147,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_PCM16B_SWB32_FUNCTIONS(inst) \ @@ -149,6 +159,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_PCM16B_SWB48_FUNCTIONS(inst) \ @@ -160,6 +171,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_FUNCTIONS(inst) \ @@ -171,6 +183,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1_16_FUNCTIONS(inst) \ @@ -182,6 +195,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1_24_FUNCTIONS(inst) \ @@ -193,6 +207,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1_32_FUNCTIONS(inst) \ @@ -204,6 +219,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1C_24_FUNCTIONS(inst) \ @@ -215,6 +231,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1C_32_FUNCTIONS(inst) \ @@ -226,6 +243,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G722_1C_48_FUNCTIONS(inst) \ @@ -237,6 +255,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_AMR_FUNCTIONS(inst) \ @@ -248,6 +267,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_AMRWB_FUNCTIONS(inst) \ @@ -259,6 +279,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_GSMFR_FUNCTIONS(inst) \ @@ -270,6 +291,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G726_16_FUNCTIONS(inst) \ @@ -281,6 +303,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G726_24_FUNCTIONS(inst) \ @@ -292,6 +315,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G726_32_FUNCTIONS(inst) \ @@ -303,6 +327,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_G726_40_FUNCTIONS(inst) \ @@ -314,6 +339,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_OPUS_FUNCTIONS(inst) \ @@ -325,6 +351,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_OPUSSLAVE_FUNCTIONS(inst) \ @@ -336,6 +363,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_SPEEX_FUNCTIONS(inst) \ @@ -347,6 +375,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_CELT_FUNCTIONS(inst) \ @@ -358,6 +387,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_CELTSLAVE_FUNCTIONS(inst) \ @@ -369,6 +399,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_RED_FUNCTIONS(inst) \ @@ -380,6 +411,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_AVT_FUNCTIONS(inst) \ @@ -391,6 +423,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #define SET_CNG_FUNCTIONS(inst) \ @@ -402,6 +435,7 @@ inst.funcGetMDinfo=NULL; \ inst.funcGetPitch=NULL; \ inst.funcUpdBWEst=NULL; \ + inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=NULL; #endif /* WEBRTC_NETEQ_HELP_MACROS_H */ diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.c b/webrtc/modules/audio_coding/neteq/packet_buffer.c index 74a4903d98..e8ee40c919 100644 --- a/webrtc/modules/audio_coding/neteq/packet_buffer.c +++ b/webrtc/modules/audio_coding/neteq/packet_buffer.c @@ -491,36 +491,79 @@ int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t* buffer_inst, return 0; } -WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst) -{ - int i, count; - WebRtc_Word32 sizeSamples; +int WebRtcNetEQ_PacketBufferGetPacketSize(const PacketBuf_t* buffer_inst, + int buffer_pos, + const CodecDbInst_t* codec_database, + int codec_pos, int last_duration) { + if (codec_database->funcDurationEst[codec_pos] == NULL) { + return last_duration; + } + return (*codec_database->funcDurationEst[codec_pos])( + codec_database->codec_state[codec_pos], + (const uint8_t *)buffer_inst->payloadLocation[buffer_pos], + buffer_inst->payloadLengthBytes[buffer_pos]); +} - count = 0; +WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t* buffer_inst, + const CodecDbInst_t* + codec_database) { + int i, count; + int last_duration; + int last_codec_pos; + int last_payload_type; + WebRtc_Word32 size_samples; - /* Loop through all slots in the buffer */ - for (i = 0; i < bufferInst->maxInsertPositions; i++) - { - /* Only count the packets with non-zero size */ - if (bufferInst->payloadLengthBytes[i] != 0) - { - count++; + count = 0; + last_duration = buffer_inst->packSizeSamples; + last_codec_pos = -1; + last_payload_type = -1; + size_samples = 0; + + /* Loop through all slots in the buffer */ + for (i = 0; i < buffer_inst->maxInsertPositions; i++) { + /* Only count the packets with non-zero size */ + if (buffer_inst->payloadLengthBytes[i] != 0) { + int payload_type; + int codec_pos; + /* Figure out the codec database entry for this payload_type. */ + payload_type = buffer_inst->payloadType[i]; + /* Remember the last one, to avoid the database search. */ + if(payload_type == last_payload_type) { + codec_pos = last_codec_pos; + } + else { + codec_pos = WebRtcNetEQ_DbGetCodec(codec_database, + payload_type); + if (codec_pos >= 0) { + codec_pos = codec_database->position[codec_pos]; } + } + last_codec_pos = codec_pos; + last_payload_type = payload_type; + if (codec_pos >= 0) { + /* + * Right now WebRtcNetEQ_PacketBufferGetPacketSize either always + * returns last_duration or always computes the real duration without + * looking at last_duration. If an implementation really wanted to use + * last_duration to compute a changing duration, we would have to + * iterate through the packets in chronological order by timestamp. + */ + last_duration = WebRtcNetEQ_PacketBufferGetPacketSize( + buffer_inst, i, codec_database, codec_pos, + last_duration); + } + /* Add in the size of this packet. */ + size_samples += last_duration; + count++; } + } - /* - * Calculate buffer size as number of packets times packet size - * (packet size is that of the latest decoded packet) - */ - sizeSamples = WEBRTC_SPL_MUL_16_16(bufferInst->packSizeSamples, count); + /* Sanity check; size cannot be negative */ + if (size_samples < 0) { + size_samples = 0; + } - /* Sanity check; size cannot be negative */ - if (sizeSamples < 0) - { - sizeSamples = 0; - } - - return sizeSamples; + return size_samples; } void WebRtcNetEQ_IncrementWaitingTimes(PacketBuf_t *buffer_inst) { diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.h b/webrtc/modules/audio_coding/neteq/packet_buffer.h index 662f8afa46..44e070af4e 100644 --- a/webrtc/modules/audio_coding/neteq/packet_buffer.h +++ b/webrtc/modules/audio_coding/neteq/packet_buffer.h @@ -167,6 +167,31 @@ int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t* buffer_inst, int erase_old_packets, int16_t* payload_type); +/**************************************************************************** + * WebRtcNetEQ_PacketBufferGetPacketSize(...) + * + * Calculate and return an estimate of the data length (in samples) of the + * given packet. If no estimate is available (because we do not know how to + * compute packet durations for the associated payload type), last_duration + * will be returned instead. + * + * Input: + * - buffer_inst : Buffer instance + * - buffer_pos : The index of the buffer of which to estimate the + * duration + * - codec_database : Codec database instance + * - codec_pos : The codec database entry associated with the payload + * type of the specified buffer. + * - last_duration : The duration of the previous frame. + * + * Return value : The buffer size in samples + */ + +int WebRtcNetEQ_PacketBufferGetPacketSize(const PacketBuf_t* buffer_inst, + int buffer_pos, + const CodecDbInst_t* codec_database, + int codec_pos, int last_duration); + /**************************************************************************** * WebRtcNetEQ_PacketBufferGetSize(...) * @@ -177,12 +202,15 @@ int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t* buffer_inst, * decoded packet. * * Input: - * - bufferInst : Buffer instance + * - buffer_inst : Buffer instance + * - codec_database : Codec database instance * - * Return value : The buffer size in samples + * Return value : The buffer size in samples */ -WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst); +WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t* buffer_inst, + const CodecDbInst_t* + codec_database); /**************************************************************************** * WebRtcNetEQ_IncrementWaitingTimes(...) diff --git a/webrtc/modules/audio_coding/neteq/recin.c b/webrtc/modules/audio_coding/neteq/recin.c index aa8a3b55c0..24e1eeed20 100644 --- a/webrtc/modules/audio_coding/neteq/recin.c +++ b/webrtc/modules/audio_coding/neteq/recin.c @@ -35,13 +35,15 @@ int WebRtcNetEQ_RecInInternal(MCUInst_t *MCU_inst, RTPPacket_t *RTPpacketInput, WebRtc_Word16 codecPos; int curr_Codec; WebRtc_Word16 isREDPayload = 0; - WebRtc_Word32 temp_bufsize = MCU_inst->PacketBuffer_inst.numPacketsInBuffer; + WebRtc_Word32 temp_bufsize; #ifdef NETEQ_RED_CODEC RTPPacket_t* RTPpacketPtr[2]; /* Support for redundancy up to 2 payloads */ RTPpacketPtr[0] = &RTPpacket[0]; RTPpacketPtr[1] = &RTPpacket[1]; #endif + temp_bufsize = WebRtcNetEQ_PacketBufferGetSize(&MCU_inst->PacketBuffer_inst, + &MCU_inst->codec_DB_inst); /* * Copy from input RTP packet to local copy * (mainly to enable multiple payloads using RED) @@ -308,8 +310,9 @@ int WebRtcNetEQ_RecInInternal(MCUInst_t *MCU_inst, RTPPacket_t *RTPpacketInput, if (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF == 0) { /* Calculate the total speech length carried in each packet */ - temp_bufsize = MCU_inst->PacketBuffer_inst.numPacketsInBuffer - temp_bufsize; - temp_bufsize *= MCU_inst->PacketBuffer_inst.packSizeSamples; + temp_bufsize = WebRtcNetEQ_PacketBufferGetSize( + &MCU_inst->PacketBuffer_inst, &MCU_inst->codec_DB_inst) + - temp_bufsize; if ((temp_bufsize > 0) && (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF == 0) && (temp_bufsize diff --git a/webrtc/modules/audio_coding/neteq/signal_mcu.c b/webrtc/modules/audio_coding/neteq/signal_mcu.c index 2cccf1a616..e51d5f25d1 100644 --- a/webrtc/modules/audio_coding/neteq/signal_mcu.c +++ b/webrtc/modules/audio_coding/neteq/signal_mcu.c @@ -31,6 +31,27 @@ extern FILE *delay_fid2; /* file pointer to delay log file */ #endif +/* + * Update the frame size, if we can. + */ +static int WebRtcNetEQ_UpdatePackSizeSamples(MCUInst_t* inst, int buffer_pos, + int payload_type, + int pack_size_samples) { + if (buffer_pos >= 0) { + int codec_pos; + codec_pos = WebRtcNetEQ_DbGetCodec(&inst->codec_DB_inst, payload_type); + if (codec_pos >= 0) { + codec_pos = inst->codec_DB_inst.position[codec_pos]; + if (codec_pos >= 0) { + return WebRtcNetEQ_PacketBufferGetPacketSize( + &inst->PacketBuffer_inst, buffer_pos, + &inst->codec_DB_inst, codec_pos, pack_size_samples); + } + } + } + return pack_size_samples; +} + /* * Signals the MCU that DSP status data is available. */ @@ -223,7 +244,8 @@ int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) } /* Check packet buffer */ - w32_bufsize = WebRtcNetEQ_PacketBufferGetSize(&inst->PacketBuffer_inst); + w32_bufsize = WebRtcNetEQ_PacketBufferGetSize(&inst->PacketBuffer_inst, + &inst->codec_DB_inst); if (dspInfo.lastMode == MODE_SUCCESS_ACCELERATE || dspInfo.lastMode == MODE_LOWEN_ACCELERATE || dspInfo.lastMode == MODE_SUCCESS_PREEMPTIVE @@ -254,6 +276,10 @@ int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) } #endif + /* Update the frame size, if we can. */ + inst->PacketBuffer_inst.packSizeSamples = + WebRtcNetEQ_UpdatePackSizeSamples(inst, i_bufferpos, payloadType, + inst->PacketBuffer_inst.packSizeSamples); /* Update statistics and make decision */ uw16_instr = WebRtcNetEQ_BufstatsDecision(&inst->BufferStat_inst, inst->PacketBuffer_inst.packSizeSamples, w32_bufsize, dspInfo.playedOutTS, @@ -350,7 +376,9 @@ int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) } /* Set the packet size by guessing */ - inst->PacketBuffer_inst.packSizeSamples = inst->timestampsPerCall * 3; + inst->PacketBuffer_inst.packSizeSamples = + WebRtcNetEQ_UpdatePackSizeSamples(inst, i_bufferpos, payloadType, + inst->timestampsPerCall * 3); WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), inst->PacketBuffer_inst.maxInsertPositions); @@ -695,7 +723,10 @@ int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) } prevSeqNo = inst->PacketBuffer_inst.seqNumber[i_bufferpos]; } - + /* Update the frame size, if we can. */ + inst->PacketBuffer_inst.packSizeSamples = + WebRtcNetEQ_UpdatePackSizeSamples(inst, i_bufferpos, + payloadType, inst->PacketBuffer_inst.packSizeSamples); } while ((totalTS < wantedNoOfTimeStamps) && (nextSeqNoAvail == 1)); } diff --git a/webrtc/modules/audio_coding/neteq/webrtc_neteq.c b/webrtc/modules/audio_coding/neteq/webrtc_neteq.c index c9ca4c14bd..599c11b5e0 100644 --- a/webrtc/modules/audio_coding/neteq/webrtc_neteq.c +++ b/webrtc/modules/audio_coding/neteq/webrtc_neteq.c @@ -648,7 +648,8 @@ int WebRtcNetEQ_CodecDbAdd(void *inst, WebRtcNetEQ_CodecDef *codecInst) codecInst->payloadType, codecInst->funcDecode, codecInst->funcDecodeRCU, codecInst->funcDecodePLC, codecInst->funcDecodeInit, codecInst->funcAddLatePkt, codecInst->funcGetMDinfo, codecInst->funcGetPitch, codecInst->funcUpdBWEst, - codecInst->funcGetErrorCode, codecInst->codec_state, codecInst->codec_fs); + codecInst->funcDurationEst, codecInst->funcGetErrorCode, + codecInst->codec_state, codecInst->codec_fs); if (ok != 0) { NetEqMainInst->ErrorCode = -ok; @@ -1179,7 +1180,8 @@ int WebRtcNetEQ_GetNetworkStatistics(void *inst, WebRtcNetEQ_NetworkStatistics * WebRtc_Word32 temp32; /* Query packet buffer for number of samples. */ temp32 = WebRtcNetEQ_PacketBufferGetSize( - &NetEqMainInst->MCUinst.PacketBuffer_inst); + &NetEqMainInst->MCUinst.PacketBuffer_inst, + &NetEqMainInst->MCUinst.codec_DB_inst); /* Divide by sample rate. * Calculate temp32 * 1000 / fs to get result in ms. */