diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn index 67515ecd74..9244a67149 100644 --- a/webrtc/modules/BUILD.gn +++ b/webrtc/modules/BUILD.gn @@ -124,6 +124,7 @@ if (rtc_include_tests) { "audio_coding/codecs/audio_decoder_factory_unittest.cc", "audio_coding/codecs/cng/audio_encoder_cng_unittest.cc", "audio_coding/codecs/cng/cng_unittest.cc", + "audio_coding/codecs/ilbc/ilbc_unittest.cc", "audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc", "audio_coding/codecs/isac/fix/source/filters_unittest.cc", "audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc", diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index ce8ab6f73b..9d426e9ab1 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -446,6 +446,7 @@ source_set("ilbc") { deps = [ ":audio_decoder_interface", ":audio_encoder_interface", + "../../base:rtc_base_approved", "../../common_audio", ] } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c b/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c index cacf3ace28..4c72a6e72f 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c @@ -16,6 +16,8 @@ ******************************************************************/ +#include "cb_construct.h" + #include "defines.h" #include "gain_dequant.h" #include "get_cd_vec.h" @@ -24,7 +26,7 @@ * Construct decoded vector from codebook and gains. *---------------------------------------------------------------*/ -void WebRtcIlbcfix_CbConstruct( +bool WebRtcIlbcfix_CbConstruct( int16_t *decvector, /* (o) Decoded vector */ int16_t *index, /* (i) Codebook indices */ int16_t *gain_index, /* (i) Gain quantization indices */ @@ -50,9 +52,12 @@ void WebRtcIlbcfix_CbConstruct( /* codebook vector construction and construction of total vector */ /* Stack based */ - WebRtcIlbcfix_GetCbVec(cbvec0, mem, (size_t)index[0], lMem, veclen); - WebRtcIlbcfix_GetCbVec(cbvec1, mem, (size_t)index[1], lMem, veclen); - WebRtcIlbcfix_GetCbVec(cbvec2, mem, (size_t)index[2], lMem, veclen); + if (!WebRtcIlbcfix_GetCbVec(cbvec0, mem, (size_t)index[0], lMem, veclen)) + return false; // Failure. + if (!WebRtcIlbcfix_GetCbVec(cbvec1, mem, (size_t)index[1], lMem, veclen)) + return false; // Failure. + if (!WebRtcIlbcfix_GetCbVec(cbvec2, mem, (size_t)index[2], lMem, veclen)) + return false; // Failure. gainPtr = &gain[0]; for (j=0;j> 14); } - return; + return true; // Success. } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.h b/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.h index b676ef97ad..45db85e4e3 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.h @@ -19,20 +19,21 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_ +#include #include "defines.h" /*----------------------------------------------------------------* * Construct decoded vector from codebook and gains. *---------------------------------------------------------------*/ -void WebRtcIlbcfix_CbConstruct( - int16_t *decvector, /* (o) Decoded vector */ - int16_t *index, /* (i) Codebook indices */ - int16_t *gain_index, /* (i) Gain quantization indices */ - int16_t *mem, /* (i) Buffer for codevector construction */ - size_t lMem, /* (i) Length of buffer */ - size_t veclen /* (i) Length of vector */ - ); - +// Returns true on success, false on failure. +bool WebRtcIlbcfix_CbConstruct( + int16_t* decvector, /* (o) Decoded vector */ + int16_t* index, /* (i) Codebook indices */ + int16_t* gain_index, /* (i) Gain quantization indices */ + int16_t* mem, /* (i) Buffer for codevector construction */ + size_t lMem, /* (i) Length of buffer */ + size_t veclen /* (i) Length of vector */ + ) WARN_UNUSED_RESULT; #endif diff --git a/webrtc/modules/audio_coding/codecs/ilbc/decode.c b/webrtc/modules/audio_coding/codecs/ilbc/decode.c index 4c8497a568..a6e045dc67 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/decode.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/decode.c @@ -28,6 +28,7 @@ #include "decode_residual.h" #include "unpack_bits.h" #include "hp_output.h" +#include "init_decode.h" #ifndef WEBRTC_ARCH_BIG_ENDIAN #include "swap_bytes.h" #endif @@ -36,7 +37,7 @@ * main decoder function *---------------------------------------------------------------*/ -void WebRtcIlbcfix_DecodeImpl( +int WebRtcIlbcfix_DecodeImpl( int16_t *decblock, /* (o) decoded signal block */ const uint16_t *bytes, /* (i) encoded signal bits */ IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state @@ -44,6 +45,9 @@ void WebRtcIlbcfix_DecodeImpl( int16_t mode /* (i) 0: bad packet, PLC, 1: normal */ ) { + const int old_mode = iLBCdec_inst->mode; + const int old_use_enhancer = iLBCdec_inst->use_enhancer; + size_t i; int16_t order_plus_one; @@ -100,7 +104,9 @@ void WebRtcIlbcfix_DecodeImpl( lsfdeq, LPC_FILTERORDER, iLBCdec_inst); /* Decode the residual using the cb and gain indexes */ - WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, decresidual, syntdenum); + if (!WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, + decresidual, syntdenum)) + goto error; /* preparing the plc for a future loss! */ WebRtcIlbcfix_DoThePlc( @@ -241,4 +247,11 @@ void WebRtcIlbcfix_DecodeImpl( if (mode==0) { /* PLC was used */ iLBCdec_inst->prev_enh_pl=1; } + + return 0; // Success. + +error: + // The decoder got sick from eating that data. Reset it and return. + WebRtcIlbcfix_InitDecode(iLBCdec_inst, old_mode, old_use_enhancer); + return -1; // Error } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/decode.h b/webrtc/modules/audio_coding/codecs/ilbc/decode.h index 0c4c2ef844..f45fedd7b3 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/decode.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/decode.h @@ -25,13 +25,14 @@ * main decoder function *---------------------------------------------------------------*/ -void WebRtcIlbcfix_DecodeImpl( - int16_t *decblock, /* (o) decoded signal block */ - const uint16_t *bytes, /* (i) encoded signal bits */ - IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state +// Returns 0 on success, -1 on error. +int WebRtcIlbcfix_DecodeImpl( + int16_t* decblock, /* (o) decoded signal block */ + const uint16_t* bytes, /* (i) encoded signal bits */ + IlbcDecoder* iLBCdec_inst, /* (i/o) the decoder state structure */ - int16_t mode /* (i) 0: bad packet, PLC, - 1: normal */ - ); + int16_t mode /* (i) 0: bad packet, PLC, + 1: normal */ + ) WARN_UNUSED_RESULT; #endif diff --git a/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c b/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c index b8a067e0f3..dd5c353cb5 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c @@ -16,6 +16,8 @@ ******************************************************************/ +#include "decode_residual.h" + #include #include "defines.h" @@ -32,7 +34,7 @@ * frame residual decoder function (subrutine to iLBC_decode) *---------------------------------------------------------------*/ -void WebRtcIlbcfix_DecodeResidual( +bool WebRtcIlbcfix_DecodeResidual( IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state structure */ iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used @@ -72,11 +74,11 @@ void WebRtcIlbcfix_DecodeResidual( /* construct decoded vector */ - WebRtcIlbcfix_CbConstruct( - &decresidual[start_pos+iLBCdec_inst->state_short_len], - iLBC_encbits->cb_index, iLBC_encbits->gain_index, - mem+CB_MEML-ST_MEM_L_TBL, - ST_MEM_L_TBL, diff); + if (!WebRtcIlbcfix_CbConstruct( + &decresidual[start_pos + iLBCdec_inst->state_short_len], + iLBC_encbits->cb_index, iLBC_encbits->gain_index, + mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff)) + return false; // Error. } else {/* put adaptive part in the beginning */ @@ -90,12 +92,11 @@ void WebRtcIlbcfix_DecodeResidual( /* construct decoded vector */ - WebRtcIlbcfix_CbConstruct( - reverseDecresidual, - iLBC_encbits->cb_index, iLBC_encbits->gain_index, - mem+CB_MEML-ST_MEM_L_TBL, - ST_MEM_L_TBL, diff - ); + if (!WebRtcIlbcfix_CbConstruct(reverseDecresidual, iLBC_encbits->cb_index, + iLBC_encbits->gain_index, + mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, + diff)) + return false; // Error. /* get decoded residual from reversed vector */ @@ -122,12 +123,12 @@ void WebRtcIlbcfix_DecodeResidual( for (subframe=0; subframestartIdx+1+subframe)*SUBL], - iLBC_encbits->cb_index+subcount*CB_NSTAGES, - iLBC_encbits->gain_index+subcount*CB_NSTAGES, - mem, MEM_LF_TBL, SUBL - ); + if (!WebRtcIlbcfix_CbConstruct( + &decresidual[(iLBC_encbits->startIdx + 1 + subframe) * SUBL], + iLBC_encbits->cb_index + subcount * CB_NSTAGES, + iLBC_encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, + SUBL)) + return false; // Error; /* update memory */ memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); @@ -160,12 +161,12 @@ void WebRtcIlbcfix_DecodeResidual( for (subframe=0; subframecb_index+subcount*CB_NSTAGES, - iLBC_encbits->gain_index+subcount*CB_NSTAGES, - mem, MEM_LF_TBL, SUBL - ); + if (!WebRtcIlbcfix_CbConstruct( + &reverseDecresidual[subframe * SUBL], + iLBC_encbits->cb_index + subcount * CB_NSTAGES, + iLBC_encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, + SUBL)) + return false; // Error. /* update memory */ memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); @@ -179,4 +180,6 @@ void WebRtcIlbcfix_DecodeResidual( WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1, reverseDecresidual, SUBL*Nback); } + + return true; // Success. } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.h b/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.h index 67f05a5768..38f896ec6d 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.h @@ -19,20 +19,22 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_ +#include #include "defines.h" /*----------------------------------------------------------------* * frame residual decoder function (subrutine to iLBC_decode) *---------------------------------------------------------------*/ -void WebRtcIlbcfix_DecodeResidual( - IlbcDecoder *iLBCdec_inst, - /* (i/o) the decoder state structure */ - iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used - for the decoding */ - int16_t *decresidual, /* (o) decoded residual frame */ - int16_t *syntdenum /* (i) the decoded synthesis filter - coefficients */ - ); +// Returns true on success, false on failure. In case of failure, the decoder +// state may be corrupted and needs resetting. +bool WebRtcIlbcfix_DecodeResidual( + IlbcDecoder* iLBCdec_inst, /* (i/o) the decoder state structure */ + iLBC_bits* iLBC_encbits, /* (i/o) Encoded bits, which are used + for the decoding */ + int16_t* decresidual, /* (o) decoded residual frame */ + int16_t* syntdenum /* (i) the decoded synthesis filter + coefficients */ + ) WARN_UNUSED_RESULT; #endif diff --git a/webrtc/modules/audio_coding/codecs/ilbc/encode.c b/webrtc/modules/audio_coding/codecs/ilbc/encode.c index 812ec8d6c7..82066876e6 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/encode.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/encode.c @@ -29,6 +29,7 @@ #include "index_conv_enc.h" #include "pack_bits.h" #include "hp_input.h" +#include "webrtc/base/checks.h" #ifdef SPLIT_10MS #include "unpack_bits.h" @@ -206,11 +207,10 @@ void WebRtcIlbcfix_EncodeImpl( /* construct decoded vector */ - WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len], - iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, - mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, - diff - ); + RTC_CHECK(WebRtcIlbcfix_CbConstruct( + &decresidual[start_pos + iLBCenc_inst->state_short_len], + iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, + mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff)); } else { /* put adaptive part in the beginning */ @@ -233,12 +233,10 @@ void WebRtcIlbcfix_EncodeImpl( 0); /* construct decoded vector */ - - WebRtcIlbcfix_CbConstruct(reverseDecresidual, - iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, - mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, - diff - ); + RTC_CHECK(WebRtcIlbcfix_CbConstruct( + reverseDecresidual, iLBCbits_inst->cb_index, + iLBCbits_inst->gain_index, mem + CB_MEML - ST_MEM_L_TBL, + ST_MEM_L_TBL, diff)); /* get decoded residual from reversed vector */ @@ -344,13 +342,11 @@ void WebRtcIlbcfix_EncodeImpl( subcount); /* construct decoded vector */ - - WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], - iLBCbits_inst->cb_index+subcount*CB_NSTAGES, - iLBCbits_inst->gain_index+subcount*CB_NSTAGES, - mem, MEM_LF_TBL, - SUBL - ); + RTC_CHECK(WebRtcIlbcfix_CbConstruct( + &decresidual[(iLBCbits_inst->startIdx + 1 + subframe) * SUBL], + iLBCbits_inst->cb_index + subcount * CB_NSTAGES, + iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, + SUBL)); /* update memory */ @@ -450,12 +446,11 @@ void WebRtcIlbcfix_EncodeImpl( subcount); /* construct decoded vector */ - - WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL], - iLBCbits_inst->cb_index+subcount*CB_NSTAGES, - iLBCbits_inst->gain_index+subcount*CB_NSTAGES, - mem, MEM_LF_TBL, SUBL - ); + RTC_CHECK(WebRtcIlbcfix_CbConstruct( + &reverseDecresidual[subframe * SUBL], + iLBCbits_inst->cb_index + subcount * CB_NSTAGES, + iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, + SUBL)); /* update memory */ memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); diff --git a/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c b/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c index d7c2e75553..272b49a71c 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c @@ -16,6 +16,8 @@ ******************************************************************/ +#include "get_cd_vec.h" + #include "defines.h" #include "constants.h" #include "create_augmented_vec.h" @@ -24,7 +26,7 @@ * Construct codebook vector for given index. *---------------------------------------------------------------*/ -void WebRtcIlbcfix_GetCbVec( +bool WebRtcIlbcfix_GetCbVec( int16_t *cbvec, /* (o) Constructed codebook vector */ int16_t *mem, /* (i) Codebook buffer */ size_t index, /* (i) Codebook index */ @@ -93,6 +95,17 @@ void WebRtcIlbcfix_GetCbVec( /* interpolated vectors */ else { + if (cbveclen < SUBL) { + // We're going to fill in cbveclen + 5 elements of tempbuff2 in + // WebRtcSpl_FilterMAFastQ12, less than the SUBL + 5 elements we'll be + // using in WebRtcIlbcfix_CreateAugmentedVec. This error is caused by + // bad values in |index| (which come from the encoded stream). Tell the + // caller that things went south, and that the decoder state is now + // corrupt (because it's half-way through an update that we can't + // complete). + return false; + } + /* Stuff zeros outside memory buffer */ memIndTest = lMem-cbveclen-CB_FILTERLEN; WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN); @@ -108,4 +121,6 @@ void WebRtcIlbcfix_GetCbVec( WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec); } } + + return true; // Success. } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.h b/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.h index 07f67a2aa5..b770e761d7 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.h @@ -19,12 +19,18 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_ -void WebRtcIlbcfix_GetCbVec( - int16_t *cbvec, /* (o) Constructed codebook vector */ - int16_t *mem, /* (i) Codebook buffer */ +#include + +#include "defines.h" + +// Returns true on success, false on failure. In case of failure, the decoder +// state may be corrupted and needs resetting. +bool WebRtcIlbcfix_GetCbVec( + int16_t* cbvec, /* (o) Constructed codebook vector */ + int16_t* mem, /* (i) Codebook buffer */ size_t index, /* (i) Codebook index */ - size_t lMem, /* (i) Length of codebook buffer */ - size_t cbveclen /* (i) Codebook vector length */ - ); + size_t lMem, /* (i) Length of codebook buffer */ + size_t cbveclen /* (i) Codebook vector length */ + ) WARN_UNUSED_RESULT; #endif diff --git a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c index 6cd9a723fd..6587e4f3f7 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c @@ -22,6 +22,7 @@ #include "encode.h" #include "init_decode.h" #include "decode.h" +#include "webrtc/base/checks.h" #include int16_t WebRtcIlbcfix_EncoderAssign(IlbcEncoderInstance** iLBC_encinst, @@ -180,11 +181,12 @@ int WebRtcIlbcfix_Decode(IlbcDecoderInstance* iLBCdec_inst, } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], - (const uint16_t*)&encoded - [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], - (IlbcDecoder*)iLBCdec_inst, 1); + if (WebRtcIlbcfix_DecodeImpl( + &decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl], + (const uint16_t*)&encoded + [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], + (IlbcDecoder*)iLBCdec_inst, 1) == -1) + return -1; i++; } /* iLBC does not support VAD/CNG yet */ @@ -208,11 +210,12 @@ int WebRtcIlbcfix_Decode20Ms(IlbcDecoderInstance* iLBCdec_inst, } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], (const uint16_t*)&encoded [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], - (IlbcDecoder*)iLBCdec_inst, 1); + (IlbcDecoder*)iLBCdec_inst, 1)) + return -1; i++; } /* iLBC does not support VAD/CNG yet */ @@ -236,11 +239,12 @@ int WebRtcIlbcfix_Decode30Ms(IlbcDecoderInstance* iLBCdec_inst, } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], (const uint16_t*)&encoded [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], - (IlbcDecoder*)iLBCdec_inst, 1); + (IlbcDecoder*)iLBCdec_inst, 1)) + return -1; i++; } /* iLBC does not support VAD/CNG yet */ @@ -255,10 +259,11 @@ size_t WebRtcIlbcfix_DecodePlc(IlbcDecoderInstance* iLBCdec_inst, uint16_t dummy; for (i=0;iblockl], &dummy, - (IlbcDecoder*)iLBCdec_inst, 0); + (IlbcDecoder*)iLBCdec_inst, 0)); } return (noOfLostFrames*((IlbcDecoder*)iLBCdec_inst)->blockl); } diff --git a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi index ffb0574588..27dfd883de 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi +++ b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi @@ -12,6 +12,7 @@ 'target_name': 'ilbc', 'type': 'static_library', 'dependencies': [ + '<(webrtc_root)/base/base.gyp:rtc_base_approved', '<(webrtc_root)/common_audio/common_audio.gyp:common_audio', 'audio_encoder_interface', ], @@ -172,6 +173,11 @@ 'ilbc', ], 'sources': [ + # The empty .cc file is a hack to get GYP to use the C++ + # linker even though all sources here are .c files; this + # is necessary because we transitively depend on + # rtc_base_approved, which calls the C++ standard library. + 'test/empty.cc', 'test/iLBC_test.c', ], }, # ilbc_test diff --git a/webrtc/modules/audio_coding/codecs/ilbc/ilbc_unittest.cc b/webrtc/modules/audio_coding/codecs/ilbc/ilbc_unittest.cc new file mode 100644 index 0000000000..c23cbc44e8 --- /dev/null +++ b/webrtc/modules/audio_coding/codecs/ilbc/ilbc_unittest.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 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. + */ + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h" + +namespace webrtc { + +TEST(IlbcTest, BadPacket) { + // Get a good packet. + AudioEncoderIlbc::Config config; + config.frame_size_ms = 20; // We need 20 ms rather than the default 30 ms; + // otherwise, all possible values of cb_index[2] + // are valid. + AudioEncoderIlbc encoder(config); + std::vector samples(encoder.SampleRateHz() / 100, 4711); + rtc::Buffer packet; + int num_10ms_chunks = 0; + while (packet.size() == 0) { + encoder.Encode(0, samples, &packet); + num_10ms_chunks += 1; + } + + // Break the packet by setting all bits of the unsigned 7-bit number + // cb_index[2] to 1, giving it a value of 127. For a 20 ms packet, this is + // too large. + EXPECT_EQ(38u, packet.size()); + rtc::Buffer bad_packet(packet.data(), packet.size()); + bad_packet[29] |= 0x3f; // Bits 1-6. + bad_packet[30] |= 0x80; // Bit 0. + + // Decode the bad packet. We expect the decoder to respond by returning -1. + AudioDecoderIlbc decoder; + std::vector decoded_samples(num_10ms_chunks * samples.size()); + AudioDecoder::SpeechType speech_type; + EXPECT_EQ(-1, decoder.Decode(bad_packet.data(), bad_packet.size(), + encoder.SampleRateHz(), + sizeof(int16_t) * decoded_samples.size(), + decoded_samples.data(), &speech_type)); + + // Decode the good packet. This should work, because the failed decoding + // should not have left the decoder in a broken state. + EXPECT_EQ(static_cast(decoded_samples.size()), + decoder.Decode(packet.data(), packet.size(), encoder.SampleRateHz(), + sizeof(int16_t) * decoded_samples.size(), + decoded_samples.data(), &speech_type)); +} + +} // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/ilbc/test/empty.cc b/webrtc/modules/audio_coding/codecs/ilbc/test/empty.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 93484036bd..582b750e43 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -175,6 +175,7 @@ 'audio_coding/codecs/audio_decoder_factory_unittest.cc', 'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc', 'audio_coding/codecs/cng/cng_unittest.cc', + 'audio_coding/codecs/ilbc/ilbc_unittest.cc', 'audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc', 'audio_coding/codecs/isac/fix/source/filters_unittest.cc', 'audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc',