]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/wmalosslessdec.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / wmalosslessdec.c
index eb1db615ae180d3ccc4af04c41361d7fcad2bcc0..f750e1a47980d1bd5d9df921f7a41e27bff0796c 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
+#include "libavutil/mem_internal.h"
 
 #include "avcodec.h"
 #include "internal.h"
@@ -164,7 +165,7 @@ typedef struct WmallDecodeCtx {
     int transient_pos[WMALL_MAX_CHANNELS];
     int seekable_tile;
 
-    int ave_sum[WMALL_MAX_CHANNELS];
+    unsigned ave_sum[WMALL_MAX_CHANNELS];
 
     int channel_residues[WMALL_MAX_CHANNELS][WMALL_BLOCK_MAX_SIZE];
 
@@ -184,11 +185,18 @@ static av_cold int decode_init(AVCodecContext *avctx)
     unsigned int channel_mask;
     int i, log2_max_num_subframes;
 
-    if (!avctx->block_align) {
-        av_log(avctx, AV_LOG_ERROR, "block_align is not set\n");
+    if (avctx->block_align <= 0 || avctx->block_align > (1<<21)) {
+        av_log(avctx, AV_LOG_ERROR, "block_align is not set or invalid\n");
         return AVERROR(EINVAL);
     }
 
+    av_assert0(avctx->channels >= 0);
+    if (avctx->channels > WMALL_MAX_CHANNELS) {
+        avpriv_request_sample(avctx,
+                              "More than " AV_STRINGIFY(WMALL_MAX_CHANNELS) " channels");
+        return AVERROR_PATCHWELCOME;
+    }
+
     s->max_frame_size = MAX_FRAMESIZE * avctx->channels;
     s->frame_data = av_mallocz(s->max_frame_size + AV_INPUT_BUFFER_PADDING_SIZE);
     if (!s->frame_data)
@@ -267,16 +275,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
                 ++s->lfe_channel;
     }
 
-    if (s->num_channels < 0) {
-        av_log(avctx, AV_LOG_ERROR, "invalid number of channels %"PRId8"\n",
-               s->num_channels);
-        return AVERROR_INVALIDDATA;
-    } else if (s->num_channels > WMALL_MAX_CHANNELS) {
-        avpriv_request_sample(avctx,
-                              "More than %d channels", WMALL_MAX_CHANNELS);
-        return AVERROR_PATCHWELCOME;
-    }
-
     s->frame = av_frame_alloc();
     if (!s->frame)
         return AVERROR(ENOMEM);
@@ -535,7 +533,8 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size)
         i++;
     }
     for (; i < tile_size; i++) {
-        int quo = 0, rem, rem_bits, residue;
+        int rem, rem_bits;
+        unsigned quo = 0, residue;
         while(get_bits1(&s->gb)) {
             quo++;
             if (get_bits_left(&s->gb) <= 0)
@@ -628,7 +627,7 @@ static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred)
     int range        = 1 << (s->bits_per_sample - 1);
 
     for (ich = 0; ich < num_channels; ich++) {
-        pred_error = s->channel_residues[ich][icoef] - pred[ich];
+        pred_error = s->channel_residues[ich][icoef] - (unsigned)pred[ich];
         if (pred_error > 0) {
             for (i = 0; i < order * num_channels; i++)
                 s->mclms_coeffs[i + ich * order * num_channels] +=
@@ -678,9 +677,9 @@ static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred)
         for (i = 0; i < ich; i++)
             pred[ich] += (uint32_t)s->channel_residues[i][icoef] *
                          s->mclms_coeffs_cur[i + num_channels * ich];
-        pred[ich] += 1 << s->mclms_scaling - 1;
+        pred[ich] += (1U << s->mclms_scaling) >> 1;
         pred[ich] >>= s->mclms_scaling;
-        s->channel_residues[ich][icoef] += pred[ich];
+        s->channel_residues[ich][icoef] += (unsigned)pred[ich];
     }
 }
 
@@ -760,13 +759,14 @@ static void lms_update ## bits (WmallDecodeCtx *s, int ich, int ilms, int input)
 static void revert_cdlms ## bits (WmallDecodeCtx *s, int ch, \
                                   int coef_begin, int coef_end) \
 { \
-    int icoef, pred, ilms, num_lms, residue, input; \
+    int icoef, ilms, num_lms, residue, input; \
+    unsigned pred;\
  \
     num_lms = s->cdlms_ttl[ch]; \
     for (ilms = num_lms - 1; ilms >= 0; ilms--) { \
         for (icoef = coef_begin; icoef < coef_end; icoef++) { \
             int##bits##_t *prevvalues = (int##bits##_t *)s->cdlms[ch][ilms].lms_prevvalues; \
-            pred = 1 << (s->cdlms[ch][ilms].scaling - 1); \
+            pred = (1 << s->cdlms[ch][ilms].scaling) >> 1; \
             residue = s->channel_residues[ch][icoef]; \
             pred += s->dsp.scalarproduct_and_madd_int## bits (s->cdlms[ch][ilms].coefs, \
                                                         prevvalues + s->cdlms[ch][ilms].recent, \
@@ -774,7 +774,7 @@ static void revert_cdlms ## bits (WmallDecodeCtx *s, int ch, \
                                                         s->cdlms[ch][ilms].recent, \
                                                         FFALIGN(s->cdlms[ch][ilms].order, ROUND), \
                                                         WMASIGN(residue)); \
-            input = residue + (pred >> s->cdlms[ch][ilms].scaling); \
+            input = residue + (unsigned)((int)pred >> s->cdlms[ch][ilms].scaling); \
             lms_update ## bits(s, ch, ilms, input); \
             s->channel_residues[ch][icoef] = input; \
         } \
@@ -792,8 +792,8 @@ static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size)
     else if (s->is_channel_coded[0] || s->is_channel_coded[1]) {
         int icoef;
         for (icoef = 0; icoef < tile_size; icoef++) {
-            s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1;
-            s->channel_residues[1][icoef] += s->channel_residues[0][icoef];
+            s->channel_residues[0][icoef] -= (unsigned)(s->channel_residues[1][icoef] >> 1);
+            s->channel_residues[1][icoef] += (unsigned) s->channel_residues[0][icoef];
         }
     }
 }
@@ -811,22 +811,25 @@ static void revert_acfilter(WmallDecodeCtx *s, int tile_size)
             pred = 0;
             for (j = 0; j < order; j++) {
                 if (i <= j)
-                    pred += filter_coeffs[j] * prevvalues[j - i];
+                    pred += (uint32_t)filter_coeffs[j] * prevvalues[j - i];
                 else
-                    pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j];
+                    pred += (uint32_t)s->channel_residues[ich][i - j - 1] * filter_coeffs[j];
             }
             pred >>= scaling;
-            s->channel_residues[ich][i] += pred;
+            s->channel_residues[ich][i] += (unsigned)pred;
         }
         for (i = order; i < tile_size; i++) {
             pred = 0;
             for (j = 0; j < order; j++)
                 pred += (uint32_t)s->channel_residues[ich][i - j - 1] * filter_coeffs[j];
             pred >>= scaling;
-            s->channel_residues[ich][i] += pred;
+            s->channel_residues[ich][i] += (unsigned)pred;
         }
-        for (j = 0; j < order; j++)
-            prevvalues[j] = s->channel_residues[ich][tile_size - j - 1];
+        for (j = order - 1; j >= 0; j--)
+            if (tile_size <= j) {
+                prevvalues[j] = prevvalues[j - tile_size];
+            }else
+                prevvalues[j] = s->channel_residues[ich][tile_size - j - 1];
     }
 }
 
@@ -930,6 +933,8 @@ static int decode_subframe(WmallDecodeCtx *s)
             s->do_lpc = 0;
     }
 
+    if (get_bits_left(&s->gb) < 1)
+        return AVERROR_INVALIDDATA;
 
     if (get_bits1(&s->gb))
         padding_zeroes = get_bits(&s->gb, 5);
@@ -950,6 +955,8 @@ static int decode_subframe(WmallDecodeCtx *s)
             for (j = 0; j < subframe_len; j++)
                 s->channel_residues[i][j] = get_sbits_long(&s->gb, bits);
     } else {
+        if (s->bits_per_sample < padding_zeroes)
+            return AVERROR_INVALIDDATA;
         for (i = 0; i < s->num_channels; i++) {
             if (s->is_channel_coded[i]) {
                 decode_channel_residues(s, i, subframe_len);
@@ -977,7 +984,7 @@ static int decode_subframe(WmallDecodeCtx *s)
         if (s->quant_stepsize != 1)
             for (i = 0; i < s->num_channels; i++)
                 for (j = 0; j < subframe_len; j++)
-                    s->channel_residues[i][j] *= s->quant_stepsize;
+                    s->channel_residues[i][j] *= (unsigned)s->quant_stepsize;
     }
 
     /* Write to proper output buffer depending on bit-depth */
@@ -987,9 +994,9 @@ static int decode_subframe(WmallDecodeCtx *s)
 
         for (j = 0; j < subframe_len; j++) {
             if (s->bits_per_sample == 16) {
-                *s->samples_16[c]++ = (int16_t) s->channel_residues[c][j] << padding_zeroes;
+                *s->samples_16[c]++ = (int16_t) s->channel_residues[c][j] * (1 << padding_zeroes);
             } else {
-                *s->samples_32[c]++ = s->channel_residues[c][j] << (padding_zeroes + 8);
+                *s->samples_32[c]++ = s->channel_residues[c][j] * (256U << padding_zeroes);
             }
         }
     }
@@ -1154,14 +1161,14 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len,
 
     s->num_saved_bits += len;
     if (!append) {
-        avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
+        ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
                          s->num_saved_bits);
     } else {
         int align = 8 - (get_bits_count(gb) & 7);
         align = FFMIN(align, len);
         put_bits(&s->pb, align, get_bits(gb, align));
         len -= align;
-        avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
+        ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
     }
     skip_bits_long(gb, len);
 
@@ -1316,7 +1323,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_wmalossless_decoder = {
+const AVCodec ff_wmalossless_decoder = {
     .name           = "wmalossless",
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"),
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -1327,6 +1334,7 @@ AVCodec ff_wmalossless_decoder = {
     .decode         = decode_packet,
     .flush          = flush,
     .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },