X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsonic.c;h=b31258eaa1784e19a19a1b45a31c3bbf6cead9c8;hb=83b6471dcb762859f20b2c414decc755fcceb5e8;hp=34d2952e69ce5304a7eb13964f72e9563f632a6e;hpb=d6b62ce1aced9e2456582870382f384581cc7cbb;p=ffmpeg diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index 34d2952e69c..b31258eaa17 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -140,10 +140,13 @@ static inline av_flatten int get_symbol(RangeCoder *c, uint8_t *state, int is_si if(get_rac(c, state+0)) return 0; else{ - int i, e, a; + int i, e; + unsigned a; e= 0; while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 e++; + if (e > 31) + return AVERROR_INVALIDDATA; } a= 1; @@ -455,8 +458,8 @@ static void predictor_init_state(int *k, int *state, int order) for (j = 0, p = i+1; p < order; j++,p++) { - int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); - state[p] += shift_down(k[j]*x, LATTICE_SHIFT); + int tmp = x + shift_down(k[j] * (unsigned)state[p], LATTICE_SHIFT); + state[p] += shift_down(k[j]* (unsigned)x, LATTICE_SHIFT); x = tmp; } } @@ -464,7 +467,7 @@ static void predictor_init_state(int *k, int *state, int order) static int predictor_calc_error(int *k, int *state, int order, int error) { - int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT); + int i, x = error - shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT); #if 1 int *k_ptr = &(k[order-2]), @@ -472,13 +475,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error) for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) { int k_value = *k_ptr, state_value = *state_ptr; - x -= shift_down(k_value * state_value, LATTICE_SHIFT); - state_ptr[1] = state_value + shift_down(k_value * x, LATTICE_SHIFT); + x -= (unsigned)shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT); + state_ptr[1] = state_value + shift_down(k_value * (unsigned)x, LATTICE_SHIFT); } #else for (i = order-2; i >= 0; i--) { - x -= shift_down(k[i] * state[i], LATTICE_SHIFT); + x -= (unsigned)shift_down(k[i] * state[i], LATTICE_SHIFT); state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT); } #endif @@ -497,16 +500,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error) // copes better with quantization, and calculates the // actual whitened result as it goes. -static int modified_levinson_durbin(int *window, int window_entries, +static void modified_levinson_durbin(int *window, int window_entries, int *out, int out_entries, int channels, int *tap_quant) { int i; - int *state = av_calloc(window_entries, sizeof(*state)); + int *state = window + window_entries; - if (!state) - return AVERROR(ENOMEM); - - memcpy(state, window, 4* window_entries); + memcpy(state, window, window_entries * sizeof(*state)); for (i = 0; i < out_entries; i++) { @@ -568,9 +568,6 @@ static int modified_levinson_durbin(int *window, int window_entries, } #endif } - - av_free(state); - return 0; } static inline int code_samplerate(int samplerate) @@ -593,6 +590,7 @@ static inline int code_samplerate(int samplerate) static av_cold int sonic_encode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; + int *coded_samples; PutBitContext pb; int i; @@ -652,17 +650,16 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) if (!s->predictor_k) return AVERROR(ENOMEM); - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); - if (!s->coded_samples[i]) - return AVERROR(ENOMEM); - } + coded_samples = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples)); + if (!coded_samples) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, coded_samples += s->block_align) + s->coded_samples[i] = coded_samples; s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); s->window_size = ((2*s->tail_size)+s->frame_size); - s->window = av_calloc(s->window_size, sizeof(*s->window)); + s->window = av_calloc(s->window_size, 2 * sizeof(*s->window)); if (!s->window || !s->int_samples) return AVERROR(ENOMEM); @@ -690,7 +687,7 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table flush_put_bits(&pb); - avctx->extradata_size = put_bits_count(&pb)/8; + avctx->extradata_size = put_bytes_output(&pb); av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); @@ -703,11 +700,8 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) static av_cold int sonic_encode_close(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->channels; i++) - av_freep(&s->coded_samples[i]); + av_freep(&s->coded_samples[0]); av_freep(&s->predictor_k); av_freep(&s->tail); av_freep(&s->tap_quant); @@ -761,7 +755,7 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, break; } - memset(s->window, 0, 4* s->window_size); + memset(s->window, 0, s->window_size * sizeof(*s->window)); for (i = 0; i < s->tail_size; i++) s->window[x++] = s->tail[i]; @@ -776,10 +770,8 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i]; // generate taps - ret = modified_levinson_durbin(s->window, s->window_size, + modified_levinson_durbin(s->window, s->window_size, s->predictor_k, s->num_taps, s->channels, s->tap_quant); - if (ret < 0) - return ret; if ((ret = intlist_write(&c, state, s->predictor_k, s->num_taps, 0)) < 0) return ret; @@ -840,8 +832,6 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return ret; } -// av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8); - avpkt->size = ff_rac_terminate(&c, 0); *got_packet_ptr = 1; return 0; @@ -856,6 +846,7 @@ static const int samplerate_table[] = static av_cold int sonic_decode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; + int *tmp; GetBitContext gb; int i; int ret; @@ -948,19 +939,18 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k)); - for (i = 0; i < s->channels; i++) - { - s->predictor_state[i] = av_calloc(s->num_taps, sizeof(**s->predictor_state)); - if (!s->predictor_state[i]) - return AVERROR(ENOMEM); - } + tmp = av_calloc(s->num_taps, s->channels * sizeof(**s->predictor_state)); + if (!tmp) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, tmp += s->num_taps) + s->predictor_state[i] = tmp; + + tmp = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples)); + if (!tmp) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, tmp += s->block_align) + s->coded_samples[i] = tmp; - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); - if (!s->coded_samples[i]) - return AVERROR(ENOMEM); - } s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); if (!s->int_samples) return AVERROR(ENOMEM); @@ -972,17 +962,12 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) static av_cold int sonic_decode_close(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; - int i; av_freep(&s->int_samples); av_freep(&s->tap_quant); av_freep(&s->predictor_k); - - for (i = 0; i < s->channels; i++) - { - av_freep(&s->predictor_state[i]); - av_freep(&s->coded_samples[i]); - } + av_freep(&s->predictor_state[0]); + av_freep(&s->coded_samples[0]); return 0; } @@ -1030,6 +1015,9 @@ static int sonic_decode_frame(AVCodecContext *avctx, { int x = ch; + if (c.overread > MAX_OVERREAD) + return AVERROR_INVALIDDATA; + predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps); intlist_read(&c, state, s->coded_samples[ch], s->block_align, 1); @@ -1042,7 +1030,7 @@ static int sonic_decode_frame(AVCodecContext *avctx, x += s->channels; } - s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * quant); + s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * (unsigned)quant); x += s->channels; } @@ -1082,7 +1070,7 @@ static int sonic_decode_frame(AVCodecContext *avctx, return buf_size; } -AVCodec ff_sonic_decoder = { +const AVCodec ff_sonic_decoder = { .name = "sonic", .long_name = NULL_IF_CONFIG_SMALL("Sonic"), .type = AVMEDIA_TYPE_AUDIO, @@ -1091,12 +1079,13 @@ AVCodec ff_sonic_decoder = { .init = sonic_decode_init, .close = sonic_decode_close, .decode = sonic_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif /* CONFIG_SONIC_DECODER */ #if CONFIG_SONIC_ENCODER -AVCodec ff_sonic_encoder = { +const AVCodec ff_sonic_encoder = { .name = "sonic", .long_name = NULL_IF_CONFIG_SMALL("Sonic"), .type = AVMEDIA_TYPE_AUDIO, @@ -1106,12 +1095,13 @@ AVCodec ff_sonic_encoder = { .encode2 = sonic_encode_frame, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = AV_CODEC_CAP_EXPERIMENTAL, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .close = sonic_encode_close, }; #endif #if CONFIG_SONIC_LS_ENCODER -AVCodec ff_sonic_ls_encoder = { +const AVCodec ff_sonic_ls_encoder = { .name = "sonicls", .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), .type = AVMEDIA_TYPE_AUDIO, @@ -1121,6 +1111,7 @@ AVCodec ff_sonic_ls_encoder = { .encode2 = sonic_encode_frame, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = AV_CODEC_CAP_EXPERIMENTAL, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .close = sonic_encode_close, }; #endif