]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/sonic.c
doc/APIchanges: add hashes and version numbers for recent entries
[ffmpeg] / libavcodec / sonic.c
index e1d37f878089567205e832901621914643603f88..b31258eaa1784e19a19a1b45a31c3bbf6cead9c8 100644 (file)
@@ -475,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 * (unsigned)state_value, 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
@@ -500,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++)
     {
@@ -571,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)
@@ -596,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;
 
@@ -655,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);
 
@@ -693,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);
@@ -706,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);
@@ -764,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];
@@ -779,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;
@@ -843,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;
@@ -859,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;
@@ -951,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);
@@ -975,15 +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 < MAX_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;
 }
@@ -1031,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);
@@ -1083,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,
@@ -1092,13 +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,
@@ -1114,7 +1101,7 @@ AVCodec ff_sonic_encoder = {
 #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,