X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fra144.c;h=81a29086cae954ffe398222550abd5e9080007b2;hb=5e12701c5c881722f28379a15a60d5a20698b10f;hp=fc99655e80a72d3b7124154ea9f5ccaac8e1ed85;hpb=fd76c37fd9f564b4e979fbe20ecfcfad13f8b4f4;p=ffmpeg diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c index fc99655e80a..81a29086cae 100644 --- a/libavcodec/ra144.c +++ b/libavcodec/ra144.c @@ -23,9 +23,9 @@ */ #include "avcodec.h" -#include "bitstream.h" +#include "get_bits.h" #include "ra144.h" -#include "acelp_filters.h" +#include "celp_filters.h" #define NBLOCKS 4 ///< number of subblocks within a block #define BLOCKSIZE 40 ///< subblock size in 16-bit words @@ -38,20 +38,20 @@ typedef struct { unsigned int lpc_tables[2][10]; /** LPC coefficients: lpc_coef[0] is the coefficients of the current frame - * and lpc_coef[1] of the previous one */ + * and lpc_coef[1] of the previous one. */ unsigned int *lpc_coef[2]; unsigned int lpc_refl_rms[2]; - /** the current subblock padded by the last 10 values of the previous one*/ + /** The current subblock padded by the last 10 values of the previous one. */ int16_t curr_sblock[50]; - /** adaptive codebook. Its size is two units bigger to avoid a - * buffer overflow */ - uint16_t adapt_cb[148]; + /** Adaptive codebook, its size is two units bigger to avoid a + * buffer overflow. */ + uint16_t adapt_cb[146+2]; } RA144Context; -static int ra144_decode_init(AVCodecContext * avctx) +static av_cold int ra144_decode_init(AVCodecContext * avctx) { RA144Context *ractx = avctx->priv_data; @@ -71,7 +71,7 @@ static int t_sqrt(unsigned int x) int s = 2; while (x > 0xfff) { s++; - x = x >> 2; + x >>= 2; } return ff_sqrt(x << 20) << s; @@ -109,12 +109,9 @@ static void copy_and_dup(int16_t *target, const int16_t *source, int offset) { source += BUFFERSIZE - offset; - if (offset > BLOCKSIZE) { - memcpy(target, source, BLOCKSIZE*sizeof(*target)); - } else { - memcpy(target, source, offset*sizeof(*target)); + memcpy(target, source, FFMIN(BLOCKSIZE, offset)*sizeof(*target)); + if (offset < BLOCKSIZE) memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target)); - } } /** inverse root mean square */ @@ -139,10 +136,15 @@ static void add_wav(int16_t *dest, int n, int skip_first, int *m, v[0] = 0; for (i=!skip_first; i<3; i++) - v[i] = (gain_val_tab[n][i] * m[i]) >> (gain_exp_tab[n][i] + 1); + v[i] = (gain_val_tab[n][i] * m[i]) >> gain_exp_tab[n]; - for (i=0; i < BLOCKSIZE; i++) - dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12; + if (v[0]) { + for (i=0; i < BLOCKSIZE; i++) + dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12; + } else { + for (i=0; i < BLOCKSIZE; i++) + dest[i] = ( s2[i]*v[1] + s3[i]*v[2]) >> 12; + } } static unsigned int rescale_rms(unsigned int rms, unsigned int energy) @@ -154,7 +156,7 @@ static unsigned int rms(const int *data) { int i; unsigned int res = 0x10000; - int b = 0; + int b = 10; for (i=0; i < 10; i++) { res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12; @@ -168,10 +170,7 @@ static unsigned int rms(const int *data) } } - res = t_sqrt(res); - - res >>= (b + 10); - return res; + return t_sqrt(res) >> b; } static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, @@ -201,19 +200,14 @@ static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE; - add_wav(block, gain, cba_idx, m, buffer_a, + add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL, cb1_vects[cb1_idx], cb2_vects[cb2_idx]); memcpy(ractx->curr_sblock, ractx->curr_sblock + 40, 10*sizeof(*ractx->curr_sblock)); - memcpy(ractx->curr_sblock + 10, block, - BLOCKSIZE*sizeof(*ractx->curr_sblock)); - - if (ff_acelp_lp_synthesis_filter( - ractx->curr_sblock + 10, lpc_coefs, - ractx->curr_sblock + 10, BLOCKSIZE, - 10, 1, 0xfff) - ) + + if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs, + block, BLOCKSIZE, 10, 1, 0xfff)) memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock)); } @@ -222,21 +216,19 @@ static void int_to_int16(int16_t *out, const int *inp) int i; for (i=0; i < 30; i++) - *(out++) = *(inp++); + *out++ = *inp++; } /** * Evaluate the reflection coefficients from the filter coefficients. * Does the inverse of the eval_coefs() function. * - * @return 1 if one of the reflection coefficients is of magnitude greater than + * @return 1 if one of the reflection coefficients is greater than * 4095, 0 if not. */ static int eval_refl(int *refl, const int16_t *coefs, RA144Context *ractx) { - int retval = 0; - int b, c, i; - unsigned int u; + int b, i, j; int buffer1[10]; int buffer2[10]; int *bp1 = buffer1; @@ -245,54 +237,47 @@ static int eval_refl(int *refl, const int16_t *coefs, RA144Context *ractx) for (i=0; i < 10; i++) buffer2[i] = coefs[i]; - u = refl[9] = bp2[9]; + refl[9] = bp2[9]; - if (u + 0x1000 > 0x1fff) { + if ((unsigned) bp2[9] + 0x1000 > 0x1fff) { av_log(ractx, AV_LOG_ERROR, "Overflow. Broken sample?\n"); return 1; } - for (c=8; c >= 0; c--) { - if (u == 0x1000) - u++; - - if (u == 0xfffff000) - u--; - - b = 0x1000-((u * u) >> 12); + for (i=8; i >= 0; i--) { + b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12); - if (b == 0) - b++; + if (!b) + b = -2; - for (u=0; u<=c; u++) - bp1[u] = ((bp2[u] - ((refl[c+1] * bp2[c-u]) >> 12)) * (0x1000000 / b)) >> 12; + for (j=0; j <= i; j++) + bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12; - refl[c] = u = bp1[c]; + if ((unsigned) bp1[i] + 0x1000 > 0x1fff) + return 1; - if ((u + 0x1000) > 0x1fff) - retval = 1; + refl[i] = bp1[i]; FFSWAP(int *, bp1, bp2); } - return retval; + return 0; } -static int interp(RA144Context *ractx, int16_t *out, int block_num, +static int interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy) { int work[10]; - int a = block_num + 1; int b = NBLOCKS - a; int i; - // Interpolate block coefficients from the this frame forth block and - // last frame forth block + // Interpolate block coefficients from the this frame's forth block and + // last frame's forth block. for (i=0; i<30; i++) out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2; if (eval_refl(work, out, ractx)) { // The interpolated coefficients are unstable, copy either new or old - // coefficients + // coefficients. int_to_int16(out, ractx->lpc_coef[copyold]); return rescale_rms(ractx->lpc_refl_rms[copyold], energy); } else { @@ -300,10 +285,12 @@ static int interp(RA144Context *ractx, int16_t *out, int block_num, } } -/** Uncompress one block (20 bytes -> 160*2 bytes) */ +/** Uncompress one block (20 bytes -> 160*2 bytes). */ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, - int *data_size, const uint8_t *buf, int buf_size) + int *data_size, AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[4]; // RMS of the reflection coefficients uint16_t block_coefs[4][30]; // LPC coefficients of each sub-block @@ -315,6 +302,9 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, RA144Context *ractx = avctx->priv_data; GetBitContext gb; + if (*data_size < 2*160) + return -1; + if(buf_size < 20) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); @@ -331,10 +321,10 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, energy = energy_tab[get_bits(&gb, 5)]; - refl_rms[0] = interp(ractx, block_coefs[0], 0, 1, ractx->old_energy); - refl_rms[1] = interp(ractx, block_coefs[1], 1, energy <= ractx->old_energy, + refl_rms[0] = interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); + refl_rms[1] = interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy, t_sqrt(energy*ractx->old_energy) >> 12); - refl_rms[2] = interp(ractx, block_coefs[2], 2, 0, energy); + refl_rms[2] = interp(ractx, block_coefs[2], 3, 0, energy); refl_rms[3] = rescale_rms(ractx->lpc_refl_rms[0], energy); int_to_int16(block_coefs[3], ractx->lpc_coef[0]);