uint8_t gc_2nd_index_bits; ///< gain codebook (second stage) index (size in bits)
uint8_t fc_signs_bits; ///< number of pulses in fixed-codebook vector
uint8_t fc_indexes_bits; ///< size (in bits) of fixed-codebook index entry
+ uint8_t block_size;
} G729FormatDescription;
typedef struct {
.gc_2nd_index_bits = GC_2ND_IDX_BITS_8K,
.fc_signs_bits = 4,
.fc_indexes_bits = 13,
+ .block_size = G729_8K_BLOCK_SIZE,
};
static const G729FormatDescription format_g729d_6k4 = {
.gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4,
.fc_signs_bits = 2,
.fc_indexes_bits = 9,
+ .block_size = G729D_6K4_BLOCK_SIZE,
};
/**
static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order)
{
- int res = 0;
+ int64_t res = 0;
while (order--)
res += *v1++ * *v2++;
+ if (res > INT32_MAX) return INT32_MAX;
+ else if (res < INT32_MIN) return INT32_MIN;
+
return res;
}
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- if (buf_size % (G729_8K_BLOCK_SIZE * avctx->channels) == 0) {
+ if (buf_size && buf_size % ((G729_8K_BLOCK_SIZE + (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)) * avctx->channels) == 0) {
packet_type = FORMAT_G729_8K;
format = &format_g729_8k;
//Reset voice decision
ctx->onset = 0;
ctx->voice_decision = DECISION_VOICE;
av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s");
- } else if (buf_size == G729D_6K4_BLOCK_SIZE * avctx->channels) {
+ } else if (buf_size == G729D_6K4_BLOCK_SIZE * avctx->channels && avctx->codec_id != AV_CODEC_ID_ACELP_KELVIN) {
packet_type = FORMAT_G729D_6K4;
format = &format_g729d_6k4;
av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s");
int bad_pitch = 0; ///< parity check failed
int is_periodic = 0; ///< whether one of the subframes is declared as periodic or not
out_frame = (int16_t*)frame->data[c];
+ if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN) {
+ if (*buf != ((avctx->channels - 1 - c) * 0x80 | 2))
+ avpriv_request_sample(avctx, "First byte value %x for channel %d", *buf, c);
+ buf++;
+ }
- for (i = 0; i < buf_size; i++)
+ for (i = 0; i < format->block_size; i++)
frame_erasure |= buf[i];
frame_erasure = !frame_erasure;
- init_get_bits(&gb, buf, 8*buf_size);
+ init_get_bits8(&gb, buf, format->block_size);
ma_predictor = get_bits(&gb, 1);
quantizer_1st = get_bits(&gb, VQ_1ST_BITS);
fc_v[i] = <
\ fc_v[i] + gain_pitch * fc_v[i-pitch_delay], i >= pitch_delay
*/
- ff_acelp_weighted_vector_sum(fc + pitch_delay_int[i],
- fc + pitch_delay_int[i],
- fc, 1 << 14,
- av_clip(ctx->past_gain_pitch[0], SHARP_MIN, SHARP_MAX),
- 0, 14,
- SUBFRAME_SIZE - pitch_delay_int[i]);
+ if (SUBFRAME_SIZE > pitch_delay_int[i])
+ ff_acelp_weighted_vector_sum(fc + pitch_delay_int[i],
+ fc + pitch_delay_int[i],
+ fc, 1 << 14,
+ av_clip(ctx->past_gain_pitch[0], SHARP_MIN, SHARP_MAX),
+ 0, 14,
+ SUBFRAME_SIZE - pitch_delay_int[i]);
memmove(ctx->past_gain_pitch+1, ctx->past_gain_pitch, 5 * sizeof(int16_t));
ctx->past_gain_code[1] = ctx->past_gain_code[0];
/* Save signal for use in next frame. */
memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t));
- buf += packet_type == FORMAT_G729_8K ? G729_8K_BLOCK_SIZE : G729D_6K4_BLOCK_SIZE;
+ buf += format->block_size;
ctx++;
}
*got_frame_ptr = 1;
- return packet_type == FORMAT_G729_8K ? G729_8K_BLOCK_SIZE * avctx->channels : G729D_6K4_BLOCK_SIZE * avctx->channels;
+ return (format->block_size + (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)) * avctx->channels;
}
static av_cold int decode_close(AVCodecContext *avctx)
.close = decode_close,
.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
};
+
+AVCodec ff_acelp_kelvin_decoder = {
+ .name = "acelp.kelvin",
+ .long_name = NULL_IF_CONFIG_SMALL("Sipro ACELP.KELVIN"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ACELP_KELVIN,
+ .priv_data_size = sizeof(G729Context),
+ .init = decoder_init,
+ .decode = decode_frame,
+ .close = decode_close,
+ .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
+};