iLBC: Handle a case of bad input data
We detect an unreasonable state (caused by a bad encoded stream) before it can lead to problems, and handle it by resetting the decoder. NOPRESUBMIT=true BUG=chromium:617124 Review-Url: https://codereview.webrtc.org/2255203002 Cr-Commit-Position: refs/heads/master@{#13888}
This commit is contained in:
@ -124,6 +124,7 @@ if (rtc_include_tests) {
|
|||||||
"audio_coding/codecs/audio_decoder_factory_unittest.cc",
|
"audio_coding/codecs/audio_decoder_factory_unittest.cc",
|
||||||
"audio_coding/codecs/cng/audio_encoder_cng_unittest.cc",
|
"audio_coding/codecs/cng/audio_encoder_cng_unittest.cc",
|
||||||
"audio_coding/codecs/cng/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/filterbanks_unittest.cc",
|
||||||
"audio_coding/codecs/isac/fix/source/filters_unittest.cc",
|
"audio_coding/codecs/isac/fix/source/filters_unittest.cc",
|
||||||
"audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc",
|
"audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc",
|
||||||
|
|||||||
@ -446,6 +446,7 @@ source_set("ilbc") {
|
|||||||
deps = [
|
deps = [
|
||||||
":audio_decoder_interface",
|
":audio_decoder_interface",
|
||||||
":audio_encoder_interface",
|
":audio_encoder_interface",
|
||||||
|
"../../base:rtc_base_approved",
|
||||||
"../../common_audio",
|
"../../common_audio",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
|
#include "cb_construct.h"
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "gain_dequant.h"
|
#include "gain_dequant.h"
|
||||||
#include "get_cd_vec.h"
|
#include "get_cd_vec.h"
|
||||||
@ -24,7 +26,7 @@
|
|||||||
* Construct decoded vector from codebook and gains.
|
* Construct decoded vector from codebook and gains.
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_CbConstruct(
|
bool WebRtcIlbcfix_CbConstruct(
|
||||||
int16_t *decvector, /* (o) Decoded vector */
|
int16_t *decvector, /* (o) Decoded vector */
|
||||||
int16_t *index, /* (i) Codebook indices */
|
int16_t *index, /* (i) Codebook indices */
|
||||||
int16_t *gain_index, /* (i) Gain quantization indices */
|
int16_t *gain_index, /* (i) Gain quantization indices */
|
||||||
@ -50,9 +52,12 @@ void WebRtcIlbcfix_CbConstruct(
|
|||||||
/* codebook vector construction and construction of total vector */
|
/* codebook vector construction and construction of total vector */
|
||||||
|
|
||||||
/* Stack based */
|
/* Stack based */
|
||||||
WebRtcIlbcfix_GetCbVec(cbvec0, mem, (size_t)index[0], lMem, veclen);
|
if (!WebRtcIlbcfix_GetCbVec(cbvec0, mem, (size_t)index[0], lMem, veclen))
|
||||||
WebRtcIlbcfix_GetCbVec(cbvec1, mem, (size_t)index[1], lMem, veclen);
|
return false; // Failure.
|
||||||
WebRtcIlbcfix_GetCbVec(cbvec2, mem, (size_t)index[2], lMem, veclen);
|
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];
|
gainPtr = &gain[0];
|
||||||
for (j=0;j<veclen;j++) {
|
for (j=0;j<veclen;j++) {
|
||||||
@ -63,5 +68,5 @@ void WebRtcIlbcfix_CbConstruct(
|
|||||||
decvector[j] = (int16_t)((a32 + 8192) >> 14);
|
decvector[j] = (int16_t)((a32 + 8192) >> 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return true; // Success.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,20 +19,21 @@
|
|||||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
|
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
|
||||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
|
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------*
|
/*----------------------------------------------------------------*
|
||||||
* Construct decoded vector from codebook and gains.
|
* Construct decoded vector from codebook and gains.
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_CbConstruct(
|
// Returns true on success, false on failure.
|
||||||
int16_t *decvector, /* (o) Decoded vector */
|
bool WebRtcIlbcfix_CbConstruct(
|
||||||
int16_t *index, /* (i) Codebook indices */
|
int16_t* decvector, /* (o) Decoded vector */
|
||||||
int16_t *gain_index, /* (i) Gain quantization indices */
|
int16_t* index, /* (i) Codebook indices */
|
||||||
int16_t *mem, /* (i) Buffer for codevector construction */
|
int16_t* gain_index, /* (i) Gain quantization indices */
|
||||||
size_t lMem, /* (i) Length of buffer */
|
int16_t* mem, /* (i) Buffer for codevector construction */
|
||||||
size_t veclen /* (i) Length of vector */
|
size_t lMem, /* (i) Length of buffer */
|
||||||
);
|
size_t veclen /* (i) Length of vector */
|
||||||
|
) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "decode_residual.h"
|
#include "decode_residual.h"
|
||||||
#include "unpack_bits.h"
|
#include "unpack_bits.h"
|
||||||
#include "hp_output.h"
|
#include "hp_output.h"
|
||||||
|
#include "init_decode.h"
|
||||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||||
#include "swap_bytes.h"
|
#include "swap_bytes.h"
|
||||||
#endif
|
#endif
|
||||||
@ -36,7 +37,7 @@
|
|||||||
* main decoder function
|
* main decoder function
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_DecodeImpl(
|
int WebRtcIlbcfix_DecodeImpl(
|
||||||
int16_t *decblock, /* (o) decoded signal block */
|
int16_t *decblock, /* (o) decoded signal block */
|
||||||
const uint16_t *bytes, /* (i) encoded signal bits */
|
const uint16_t *bytes, /* (i) encoded signal bits */
|
||||||
IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
|
IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
|
||||||
@ -44,6 +45,9 @@ void WebRtcIlbcfix_DecodeImpl(
|
|||||||
int16_t mode /* (i) 0: bad packet, PLC,
|
int16_t mode /* (i) 0: bad packet, PLC,
|
||||||
1: normal */
|
1: normal */
|
||||||
) {
|
) {
|
||||||
|
const int old_mode = iLBCdec_inst->mode;
|
||||||
|
const int old_use_enhancer = iLBCdec_inst->use_enhancer;
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
int16_t order_plus_one;
|
int16_t order_plus_one;
|
||||||
|
|
||||||
@ -100,7 +104,9 @@ void WebRtcIlbcfix_DecodeImpl(
|
|||||||
lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
|
lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
|
||||||
|
|
||||||
/* Decode the residual using the cb and gain indexes */
|
/* 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! */
|
/* preparing the plc for a future loss! */
|
||||||
WebRtcIlbcfix_DoThePlc(
|
WebRtcIlbcfix_DoThePlc(
|
||||||
@ -241,4 +247,11 @@ void WebRtcIlbcfix_DecodeImpl(
|
|||||||
if (mode==0) { /* PLC was used */
|
if (mode==0) { /* PLC was used */
|
||||||
iLBCdec_inst->prev_enh_pl=1;
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,14 @@
|
|||||||
* main decoder function
|
* main decoder function
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_DecodeImpl(
|
// Returns 0 on success, -1 on error.
|
||||||
int16_t *decblock, /* (o) decoded signal block */
|
int WebRtcIlbcfix_DecodeImpl(
|
||||||
const uint16_t *bytes, /* (i) encoded signal bits */
|
int16_t* decblock, /* (o) decoded signal block */
|
||||||
IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
|
const uint16_t* bytes, /* (i) encoded signal bits */
|
||||||
|
IlbcDecoder* iLBCdec_inst, /* (i/o) the decoder state
|
||||||
structure */
|
structure */
|
||||||
int16_t mode /* (i) 0: bad packet, PLC,
|
int16_t mode /* (i) 0: bad packet, PLC,
|
||||||
1: normal */
|
1: normal */
|
||||||
);
|
) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
|
#include "decode_residual.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
@ -32,7 +34,7 @@
|
|||||||
* frame residual decoder function (subrutine to iLBC_decode)
|
* frame residual decoder function (subrutine to iLBC_decode)
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_DecodeResidual(
|
bool WebRtcIlbcfix_DecodeResidual(
|
||||||
IlbcDecoder *iLBCdec_inst,
|
IlbcDecoder *iLBCdec_inst,
|
||||||
/* (i/o) the decoder state structure */
|
/* (i/o) the decoder state structure */
|
||||||
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
|
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
|
||||||
@ -72,11 +74,11 @@ void WebRtcIlbcfix_DecodeResidual(
|
|||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
|
||||||
WebRtcIlbcfix_CbConstruct(
|
if (!WebRtcIlbcfix_CbConstruct(
|
||||||
&decresidual[start_pos+iLBCdec_inst->state_short_len],
|
&decresidual[start_pos + iLBCdec_inst->state_short_len],
|
||||||
iLBC_encbits->cb_index, iLBC_encbits->gain_index,
|
iLBC_encbits->cb_index, iLBC_encbits->gain_index,
|
||||||
mem+CB_MEML-ST_MEM_L_TBL,
|
mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff))
|
||||||
ST_MEM_L_TBL, diff);
|
return false; // Error.
|
||||||
|
|
||||||
}
|
}
|
||||||
else {/* put adaptive part in the beginning */
|
else {/* put adaptive part in the beginning */
|
||||||
@ -90,12 +92,11 @@ void WebRtcIlbcfix_DecodeResidual(
|
|||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
|
||||||
WebRtcIlbcfix_CbConstruct(
|
if (!WebRtcIlbcfix_CbConstruct(reverseDecresidual, iLBC_encbits->cb_index,
|
||||||
reverseDecresidual,
|
iLBC_encbits->gain_index,
|
||||||
iLBC_encbits->cb_index, iLBC_encbits->gain_index,
|
mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL,
|
||||||
mem+CB_MEML-ST_MEM_L_TBL,
|
diff))
|
||||||
ST_MEM_L_TBL, diff
|
return false; // Error.
|
||||||
);
|
|
||||||
|
|
||||||
/* get decoded residual from reversed vector */
|
/* get decoded residual from reversed vector */
|
||||||
|
|
||||||
@ -122,12 +123,12 @@ void WebRtcIlbcfix_DecodeResidual(
|
|||||||
for (subframe=0; subframe<Nfor; subframe++) {
|
for (subframe=0; subframe<Nfor; subframe++) {
|
||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
WebRtcIlbcfix_CbConstruct(
|
if (!WebRtcIlbcfix_CbConstruct(
|
||||||
&decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL],
|
&decresidual[(iLBC_encbits->startIdx + 1 + subframe) * SUBL],
|
||||||
iLBC_encbits->cb_index+subcount*CB_NSTAGES,
|
iLBC_encbits->cb_index + subcount * CB_NSTAGES,
|
||||||
iLBC_encbits->gain_index+subcount*CB_NSTAGES,
|
iLBC_encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
|
||||||
mem, MEM_LF_TBL, SUBL
|
SUBL))
|
||||||
);
|
return false; // Error;
|
||||||
|
|
||||||
/* update memory */
|
/* update memory */
|
||||||
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
||||||
@ -160,12 +161,12 @@ void WebRtcIlbcfix_DecodeResidual(
|
|||||||
for (subframe=0; subframe<Nback; subframe++) {
|
for (subframe=0; subframe<Nback; subframe++) {
|
||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
WebRtcIlbcfix_CbConstruct(
|
if (!WebRtcIlbcfix_CbConstruct(
|
||||||
&reverseDecresidual[subframe*SUBL],
|
&reverseDecresidual[subframe * SUBL],
|
||||||
iLBC_encbits->cb_index+subcount*CB_NSTAGES,
|
iLBC_encbits->cb_index + subcount * CB_NSTAGES,
|
||||||
iLBC_encbits->gain_index+subcount*CB_NSTAGES,
|
iLBC_encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
|
||||||
mem, MEM_LF_TBL, SUBL
|
SUBL))
|
||||||
);
|
return false; // Error.
|
||||||
|
|
||||||
/* update memory */
|
/* update memory */
|
||||||
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
||||||
@ -179,4 +180,6 @@ void WebRtcIlbcfix_DecodeResidual(
|
|||||||
WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1,
|
WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1,
|
||||||
reverseDecresidual, SUBL*Nback);
|
reverseDecresidual, SUBL*Nback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true; // Success.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,20 +19,22 @@
|
|||||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
|
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
|
||||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
|
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------*
|
/*----------------------------------------------------------------*
|
||||||
* frame residual decoder function (subrutine to iLBC_decode)
|
* frame residual decoder function (subrutine to iLBC_decode)
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_DecodeResidual(
|
// Returns true on success, false on failure. In case of failure, the decoder
|
||||||
IlbcDecoder *iLBCdec_inst,
|
// state may be corrupted and needs resetting.
|
||||||
/* (i/o) the decoder state structure */
|
bool WebRtcIlbcfix_DecodeResidual(
|
||||||
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
|
IlbcDecoder* iLBCdec_inst, /* (i/o) the decoder state structure */
|
||||||
for the decoding */
|
iLBC_bits* iLBC_encbits, /* (i/o) Encoded bits, which are used
|
||||||
int16_t *decresidual, /* (o) decoded residual frame */
|
for the decoding */
|
||||||
int16_t *syntdenum /* (i) the decoded synthesis filter
|
int16_t* decresidual, /* (o) decoded residual frame */
|
||||||
coefficients */
|
int16_t* syntdenum /* (i) the decoded synthesis filter
|
||||||
);
|
coefficients */
|
||||||
|
) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#include "index_conv_enc.h"
|
#include "index_conv_enc.h"
|
||||||
#include "pack_bits.h"
|
#include "pack_bits.h"
|
||||||
#include "hp_input.h"
|
#include "hp_input.h"
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
|
|
||||||
#ifdef SPLIT_10MS
|
#ifdef SPLIT_10MS
|
||||||
#include "unpack_bits.h"
|
#include "unpack_bits.h"
|
||||||
@ -206,11 +207,10 @@ void WebRtcIlbcfix_EncodeImpl(
|
|||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
|
||||||
WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len],
|
RTC_CHECK(WebRtcIlbcfix_CbConstruct(
|
||||||
iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
|
&decresidual[start_pos + iLBCenc_inst->state_short_len],
|
||||||
mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
|
iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
|
||||||
diff
|
mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff));
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else { /* put adaptive part in the beginning */
|
else { /* put adaptive part in the beginning */
|
||||||
@ -233,12 +233,10 @@ void WebRtcIlbcfix_EncodeImpl(
|
|||||||
0);
|
0);
|
||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
RTC_CHECK(WebRtcIlbcfix_CbConstruct(
|
||||||
WebRtcIlbcfix_CbConstruct(reverseDecresidual,
|
reverseDecresidual, iLBCbits_inst->cb_index,
|
||||||
iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
|
iLBCbits_inst->gain_index, mem + CB_MEML - ST_MEM_L_TBL,
|
||||||
mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
|
ST_MEM_L_TBL, diff));
|
||||||
diff
|
|
||||||
);
|
|
||||||
|
|
||||||
/* get decoded residual from reversed vector */
|
/* get decoded residual from reversed vector */
|
||||||
|
|
||||||
@ -344,13 +342,11 @@ void WebRtcIlbcfix_EncodeImpl(
|
|||||||
subcount);
|
subcount);
|
||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
RTC_CHECK(WebRtcIlbcfix_CbConstruct(
|
||||||
WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
|
&decresidual[(iLBCbits_inst->startIdx + 1 + subframe) * SUBL],
|
||||||
iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
|
iLBCbits_inst->cb_index + subcount * CB_NSTAGES,
|
||||||
iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
|
iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
|
||||||
mem, MEM_LF_TBL,
|
SUBL));
|
||||||
SUBL
|
|
||||||
);
|
|
||||||
|
|
||||||
/* update memory */
|
/* update memory */
|
||||||
|
|
||||||
@ -450,12 +446,11 @@ void WebRtcIlbcfix_EncodeImpl(
|
|||||||
subcount);
|
subcount);
|
||||||
|
|
||||||
/* construct decoded vector */
|
/* construct decoded vector */
|
||||||
|
RTC_CHECK(WebRtcIlbcfix_CbConstruct(
|
||||||
WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL],
|
&reverseDecresidual[subframe * SUBL],
|
||||||
iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
|
iLBCbits_inst->cb_index + subcount * CB_NSTAGES,
|
||||||
iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
|
iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
|
||||||
mem, MEM_LF_TBL, SUBL
|
SUBL));
|
||||||
);
|
|
||||||
|
|
||||||
/* update memory */
|
/* update memory */
|
||||||
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
|
#include "get_cd_vec.h"
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "create_augmented_vec.h"
|
#include "create_augmented_vec.h"
|
||||||
@ -24,7 +26,7 @@
|
|||||||
* Construct codebook vector for given index.
|
* Construct codebook vector for given index.
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
void WebRtcIlbcfix_GetCbVec(
|
bool WebRtcIlbcfix_GetCbVec(
|
||||||
int16_t *cbvec, /* (o) Constructed codebook vector */
|
int16_t *cbvec, /* (o) Constructed codebook vector */
|
||||||
int16_t *mem, /* (i) Codebook buffer */
|
int16_t *mem, /* (i) Codebook buffer */
|
||||||
size_t index, /* (i) Codebook index */
|
size_t index, /* (i) Codebook index */
|
||||||
@ -93,6 +95,17 @@ void WebRtcIlbcfix_GetCbVec(
|
|||||||
/* interpolated vectors */
|
/* interpolated vectors */
|
||||||
|
|
||||||
else {
|
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 */
|
/* Stuff zeros outside memory buffer */
|
||||||
memIndTest = lMem-cbveclen-CB_FILTERLEN;
|
memIndTest = lMem-cbveclen-CB_FILTERLEN;
|
||||||
WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);
|
WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);
|
||||||
@ -108,4 +121,6 @@ void WebRtcIlbcfix_GetCbVec(
|
|||||||
WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec);
|
WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true; // Success.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,18 @@
|
|||||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_
|
#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_
|
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_
|
||||||
|
|
||||||
void WebRtcIlbcfix_GetCbVec(
|
#include <stdbool.h>
|
||||||
int16_t *cbvec, /* (o) Constructed codebook vector */
|
|
||||||
int16_t *mem, /* (i) Codebook buffer */
|
#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 index, /* (i) Codebook index */
|
||||||
size_t lMem, /* (i) Length of codebook buffer */
|
size_t lMem, /* (i) Length of codebook buffer */
|
||||||
size_t cbveclen /* (i) Codebook vector length */
|
size_t cbveclen /* (i) Codebook vector length */
|
||||||
);
|
) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "encode.h"
|
#include "encode.h"
|
||||||
#include "init_decode.h"
|
#include "init_decode.h"
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int16_t WebRtcIlbcfix_EncoderAssign(IlbcEncoderInstance** iLBC_encinst,
|
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)<len) {
|
while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)<len) {
|
||||||
WebRtcIlbcfix_DecodeImpl(
|
if (WebRtcIlbcfix_DecodeImpl(
|
||||||
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
||||||
(const uint16_t*)&encoded
|
(const uint16_t*)&encoded
|
||||||
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
||||||
(IlbcDecoder*)iLBCdec_inst, 1);
|
(IlbcDecoder*)iLBCdec_inst, 1) == -1)
|
||||||
|
return -1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* iLBC does not support VAD/CNG yet */
|
/* 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)<len) {
|
while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)<len) {
|
||||||
WebRtcIlbcfix_DecodeImpl(
|
if (!WebRtcIlbcfix_DecodeImpl(
|
||||||
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
||||||
(const uint16_t*)&encoded
|
(const uint16_t*)&encoded
|
||||||
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
||||||
(IlbcDecoder*)iLBCdec_inst, 1);
|
(IlbcDecoder*)iLBCdec_inst, 1))
|
||||||
|
return -1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* iLBC does not support VAD/CNG yet */
|
/* 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)<len) {
|
while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)<len) {
|
||||||
WebRtcIlbcfix_DecodeImpl(
|
if (!WebRtcIlbcfix_DecodeImpl(
|
||||||
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl],
|
||||||
(const uint16_t*)&encoded
|
(const uint16_t*)&encoded
|
||||||
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
[2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words],
|
||||||
(IlbcDecoder*)iLBCdec_inst, 1);
|
(IlbcDecoder*)iLBCdec_inst, 1))
|
||||||
|
return -1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* iLBC does not support VAD/CNG yet */
|
/* iLBC does not support VAD/CNG yet */
|
||||||
@ -255,10 +259,11 @@ size_t WebRtcIlbcfix_DecodePlc(IlbcDecoderInstance* iLBCdec_inst,
|
|||||||
uint16_t dummy;
|
uint16_t dummy;
|
||||||
|
|
||||||
for (i=0;i<noOfLostFrames;i++) {
|
for (i=0;i<noOfLostFrames;i++) {
|
||||||
/* call decoder */
|
// PLC decoding shouldn't fail, because there is no external input data
|
||||||
WebRtcIlbcfix_DecodeImpl(
|
// that can be bad.
|
||||||
|
RTC_CHECK(WebRtcIlbcfix_DecodeImpl(
|
||||||
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl], &dummy,
|
&decoded[i * ((IlbcDecoder*)iLBCdec_inst)->blockl], &dummy,
|
||||||
(IlbcDecoder*)iLBCdec_inst, 0);
|
(IlbcDecoder*)iLBCdec_inst, 0));
|
||||||
}
|
}
|
||||||
return (noOfLostFrames*((IlbcDecoder*)iLBCdec_inst)->blockl);
|
return (noOfLostFrames*((IlbcDecoder*)iLBCdec_inst)->blockl);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
'target_name': 'ilbc',
|
'target_name': 'ilbc',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
'<(webrtc_root)/base/base.gyp:rtc_base_approved',
|
||||||
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
|
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
|
||||||
'audio_encoder_interface',
|
'audio_encoder_interface',
|
||||||
],
|
],
|
||||||
@ -172,6 +173,11 @@
|
|||||||
'ilbc',
|
'ilbc',
|
||||||
],
|
],
|
||||||
'sources': [
|
'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',
|
'test/iLBC_test.c',
|
||||||
],
|
],
|
||||||
}, # ilbc_test
|
}, # ilbc_test
|
||||||
|
|||||||
57
webrtc/modules/audio_coding/codecs/ilbc/ilbc_unittest.cc
Normal file
57
webrtc/modules/audio_coding/codecs/ilbc/ilbc_unittest.cc
Normal file
@ -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<int16_t> 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<int16_t> 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<int>(decoded_samples.size()),
|
||||||
|
decoder.Decode(packet.data(), packet.size(), encoder.SampleRateHz(),
|
||||||
|
sizeof(int16_t) * decoded_samples.size(),
|
||||||
|
decoded_samples.data(), &speech_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -175,6 +175,7 @@
|
|||||||
'audio_coding/codecs/audio_decoder_factory_unittest.cc',
|
'audio_coding/codecs/audio_decoder_factory_unittest.cc',
|
||||||
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
||||||
'audio_coding/codecs/cng/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/filterbanks_unittest.cc',
|
||||||
'audio_coding/codecs/isac/fix/source/filters_unittest.cc',
|
'audio_coding/codecs/isac/fix/source/filters_unittest.cc',
|
||||||
'audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc',
|
'audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc',
|
||||||
|
|||||||
Reference in New Issue
Block a user