]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/sonic.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / sonic.c
index 34d2952e69ce5304a7eb13964f72e9563f632a6e..b31258eaa1784e19a19a1b45a31c3bbf6cead9c8 100644 (file)
@@ -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