diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index 507309a362..9a84989e91 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -328,13 +328,13 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag) { struct silk_context *context = codec->private_info; - SKP_int16 ret, len; int16_t *target = decoded_data; switch_core_session_t *session = codec->session; switch_jb_t *jb = NULL; SKP_int lost_flag = (*flag & SFF_PLC); switch_bool_t did_lbrr = SWITCH_FALSE; int i; + int decoded_frames = 0; *decoded_data_len = 0; @@ -368,6 +368,8 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, } do { + SKP_int16 ret, len = 0; + ret = (SKP_int16)SKP_Silk_SDK_Decode(context->dec_state, &context->decoder_object, lost_flag, @@ -379,12 +381,21 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SKP_Silk_Decode returned %d!\n", ret); printSilkError(ret); /* if FEC was activated, we can ignore bit errors*/ - if (! (ret == SKP_SILK_DEC_PAYLOAD_ERROR && did_lbrr)) - return SWITCH_STATUS_FALSE; + if (! (ret == SKP_SILK_DEC_PAYLOAD_ERROR && did_lbrr)) { + return SWITCH_STATUS_FALSE; + } } - target += len; - *decoded_data_len += (len * 2); + if (len > 0) { + target += len; + *decoded_data_len += (len * 2); + } + + /* A conformant SILK packet decodes to at most MAX_INPUT_FRAMES internal frames; stop there so + the accumulated PCM cannot run past the destination buffer regardless of the bitstream. */ + if (++decoded_frames >= MAX_INPUT_FRAMES) { + break; + } } while (context->decoder_object.moreInternalDecoderFrames); return SWITCH_STATUS_SUCCESS;