diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h b/webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h index 942727ab4..c113b034c 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h +++ b/webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h @@ -350,6 +350,7 @@ extern "C" { * * Input: * - encoded : Encoded bitstream + * - encoded_len_bytes : Length of the bitstream in bytes. * * Output: * - frameLength : Length of frame in packet (in samples) @@ -357,6 +358,7 @@ extern "C" { */ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded, + int encoded_len_bytes, int16_t* frameLength); /**************************************************************************** @@ -599,6 +601,7 @@ extern "C" { * * Input: * - encoded : Encoded bitstream + * - encoded_len_bytes : Length of the bitstream in bytes. * * Output: * - rateIndex : Bandwidth estimate in bitstream @@ -606,6 +609,7 @@ extern "C" { */ int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded, + int encoded_len_bytes, int16_t* rateIndex); diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c index 118fd2fe3..44fff0e92 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c +++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c @@ -35,6 +35,19 @@ Time2Spec WebRtcIsacfix_Time2Spec; MatrixProduct1 WebRtcIsacfix_MatrixProduct1; MatrixProduct2 WebRtcIsacfix_MatrixProduct2; +/* This method assumes that |stream_size_bytes| is in valid range, + * i.e. >= 0 && <= STREAM_MAXW16_60MS + */ +static void InitializeDecoderBitstream(int stream_size_bytes, + Bitstr_dec* bitstream) { + bitstream->W_upper = 0xFFFFFFFF; + bitstream->streamval = 0; + bitstream->stream_index = 0; + bitstream->full = 1; + bitstream->stream_size = (stream_size_bytes + 1) >> 1; + memset(bitstream->stream, 0, sizeof(bitstream->stream)); +} + /************************************************************************** * WebRtcIsacfix_AssignSize(...) * @@ -388,6 +401,7 @@ int16_t WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst, byte. */ stream_len_even = stream_len % 2 == 0 ? stream_len : stream_len + 1; + /* convert from bytes to int16_t */ #ifndef WEBRTC_ARCH_BIG_ENDIAN /* The encoded data vector is supposesd to be big-endian, but our internal representation is little-endian. So byteswap. */ @@ -632,6 +646,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst, int k; #endif int16_t err; + const int kRequiredEncodedLenBytes = 10; /* typecast pointer to real structure */ ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; @@ -653,17 +668,14 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst, return (-1); } - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - streamdata.full = 1; + InitializeDecoderBitstream(packet_size, &streamdata); #ifndef WEBRTC_ARCH_BIG_ENDIAN - for (k=0; k<5; k++) { + for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) { streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); } #else - memcpy(streamdata.stream, encoded, 5); + memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes); #endif err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj, @@ -716,6 +728,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst, int k; #endif int16_t err; + const int kRequiredEncodedLenBytes = 10; /* typecast pointer to real structure */ ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; @@ -725,6 +738,9 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst, /* return error code if the packet length is null or less */ ISAC_inst->errorcode = ISAC_EMPTY_PACKET; return -1; + } else if (packet_size < kRequiredEncodedLenBytes) { + ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT; + return -1; } else if (packet_size > (STREAM_MAXW16<<1)) { /* return error code if length of stream is too long */ ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; @@ -737,17 +753,14 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst, return (-1); } - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - streamdata.full = 1; + InitializeDecoderBitstream(packet_size, &streamdata); #ifndef WEBRTC_ARCH_BIG_ENDIAN - for (k=0; k<5; k++) { + for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) { streamdata.stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); } #else - memcpy(streamdata.stream, encoded, 5); + memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes); #endif err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj, @@ -823,7 +836,7 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst, return -1; } - ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1; + InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj); /* convert bitstream from int16_t to bytes */ #ifndef WEBRTC_ARCH_BIG_ENDIAN @@ -832,6 +845,8 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst, } if (len & 0x0001) (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8); +#else + memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len); #endif /* added for NetEq purposes (VAD/DTX related) */ @@ -917,14 +932,17 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst, return (-1); } - if (len == 0) - { /* return error code if the packet length is null */ - + if (len <= 0) { + /* return error code if the packet length is null or less */ ISAC_inst->errorcode = ISAC_EMPTY_PACKET; return -1; + } else if (len > (STREAM_MAXW16<<1)) { + /* return error code if length of stream is too long */ + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + return -1; } - ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1; + InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj); /* convert bitstream from int16_t to bytes */ #ifndef WEBRTC_ARCH_BIG_ENDIAN @@ -933,6 +951,8 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst, } if (len & 0x0001) (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8); +#else + memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len); #endif /* added for NetEq purposes (VAD/DTX related) */ @@ -1296,6 +1316,7 @@ int16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst, */ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded, + int encoded_len_bytes, int16_t* frameLength) { Bitstr_dec streamdata; @@ -1303,18 +1324,20 @@ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded, int k; #endif int16_t err; + const int kRequiredEncodedLenBytes = 10; - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - streamdata.full = 1; + if (encoded_len_bytes < kRequiredEncodedLenBytes) { + return -1; + } + + InitializeDecoderBitstream(encoded_len_bytes, &streamdata); #ifndef WEBRTC_ARCH_BIG_ENDIAN - for (k=0; k<5; k++) { + for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) { streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); } #else - memcpy(streamdata.stream, encoded, 5); + memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes); #endif /* decode frame length */ @@ -1341,6 +1364,7 @@ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded, */ int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded, + int encoded_len_bytes, int16_t* rateIndex) { Bitstr_dec streamdata; @@ -1348,18 +1372,20 @@ int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded, int k; #endif int16_t err; + const int kRequiredEncodedLenBytes = 10; - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; - streamdata.full = 1; + if (encoded_len_bytes < kRequiredEncodedLenBytes) { + return -1; + } + + InitializeDecoderBitstream(encoded_len_bytes, &streamdata); #ifndef WEBRTC_ARCH_BIG_ENDIAN - for (k=0; k<5; k++) { + for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) { streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); } #else - memcpy(streamdata.stream, encoded, 5); + memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes); #endif /* decode frame length, needed to get to the rateIndex in the bitstream */ diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h b/webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h index 2149480f6..82eb51a23 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h +++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h @@ -96,7 +96,16 @@ #define STREAM_MAXW16 300 /* The old maximum size still needed for the decoding */ #define STREAM_MAXW16_30MS 100 /* 100 Word16 = 200 bytes = 53.4 kbit/s @ 30 ms.framelength */ #define STREAM_MAXW16_60MS 200 /* 200 Word16 = 400 bytes = 53.4 kbit/s @ 60 ms.framelength */ - +/* This is used only at the decoder bit-stream struct. + * - The encoder and decoder bitstream containers are of different size because + * old iSAC limited the encoded bitstream to 600 bytes. But newer versions + * restrict to shorter bitstream. + * - We add 10 bytes of guards to the internal bitstream container. The reason + * is that entropy decoder might read few bytes (3 according to our + * observations) more than the actual size of the bitstream. To avoid reading + * outside memory, in rare occasion of full-size bitstream we add 10 bytes + * of guard. */ +#define INTERNAL_STREAM_SIZE_W16 (STREAM_MAXW16 + 5) /* storage size for bit counts */ //#define BIT_COUNTER_SIZE 30 @@ -190,6 +199,7 @@ /* 6600 Decoder */ #define ISAC_DECODER_NOT_INITIATED 6610 #define ISAC_EMPTY_PACKET 6620 +#define ISAC_PACKET_TOO_SHORT 6625 #define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630 #define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640 #define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650 diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h b/webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h index 1777efde5..0e84cd097 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h +++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h @@ -26,7 +26,7 @@ /* Bitstream struct for decoder */ typedef struct Bitstreamstruct_dec { - uint16_t stream[STREAM_MAXW16_60MS]; /* Array bytestream to decode */ + uint16_t stream[INTERNAL_STREAM_SIZE_W16]; /* Array bytestream to decode */ uint32_t W_upper; /* Upper boundary of interval W */ uint32_t streamval; uint16_t stream_index; /* Index to the current position in bytestream */ diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/test/kenny.cc b/webrtc/modules/audio_coding/codecs/isac/fix/test/kenny.cc index 91c4d76ab..39a413b6a 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/test/kenny.cc +++ b/webrtc/modules/audio_coding/codecs/isac/fix/test/kenny.cc @@ -571,7 +571,8 @@ int main(int argc, char* argv[]) functions from the internal API. */ if (stream_len>0) { if (testCE == 1) { - err = WebRtcIsacfix_ReadBwIndex((int16_t*)streamdata, &bwe); + err = WebRtcIsacfix_ReadBwIndex( + (int16_t*)streamdata, stream_len, &bwe); stream_len = WebRtcIsacfix_GetNewBitStream( ISAC_main_inst, bwe, @@ -740,7 +741,8 @@ int main(int argc, char* argv[]) if (nbTest !=2 ) { short FL; /* Call getFramelen, only used here for function test */ - err = WebRtcIsacfix_ReadFrameLen((int16_t*)streamdata, &FL); + err = WebRtcIsacfix_ReadFrameLen( + (int16_t*)streamdata, stream_len, &FL); declen = WebRtcIsacfix_Decode( ISAC_main_inst, streamdata, stream_len, decoded, speechType ); /* Error check */