]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/apedec.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / apedec.c
index 9713735574770cf25486c6ee4b2865adbcff1e96..022a6f9398c8dac7ba8b8021c71764327ecf91cb 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/crc.h"
 #include "libavutil/opt.h"
 #include "lossless_audiodsp.h"
 #include "avcodec.h"
@@ -132,6 +133,21 @@ typedef struct APEPredictor {
     unsigned int sample_pos;
 } APEPredictor;
 
+typedef struct APEPredictor64 {
+    int64_t *buf;
+
+    int64_t lastA[2];
+
+    int64_t filterA[2];
+    int64_t filterB[2];
+
+    uint64_t coeffsA[2][4];  ///< adaption coefficients
+    uint64_t coeffsB[2][5];  ///< adaption coefficients
+    int64_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE];
+
+    unsigned int sample_pos;
+} APEPredictor64;
+
 /** Decoder context */
 typedef struct APEContext {
     AVClass *class;                          ///< class for AVOptions
@@ -147,9 +163,11 @@ typedef struct APEContext {
     int fset;                                ///< which filter set to use (calculated from compression level)
     int flags;                               ///< global decoder flags
 
-    uint32_t CRC;                            ///< frame CRC
+    uint32_t CRC;                            ///< signalled frame CRC
+    uint32_t CRC_state;                      ///< accumulated CRC
     int frameflags;                          ///< frame flags
     APEPredictor predictor;                  ///< predictor used for final reconstruction
+    APEPredictor64 predictor64;              ///< 64bit predictor used for final reconstruction
 
     int32_t *decoded_buffer;
     int decoded_size;
@@ -225,6 +243,7 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
         return AVERROR(EINVAL);
     }
+    avctx->bits_per_raw_sample =
     s->bps = avctx->bits_per_coded_sample;
     switch (s->bps) {
     case 8:
@@ -260,9 +279,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
     for (i = 0; i < APE_FILTER_LEVELS; i++) {
         if (!ape_filter_orders[s->fset][i])
             break;
-        FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i],
-                         (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4,
-                         filter_alloc_fail);
+        if (!(s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4)))
+            return AVERROR(ENOMEM);
     }
 
     if (s->fileversion < 3860) {
@@ -298,9 +316,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
 
     return 0;
-filter_alloc_fail:
-    ape_decode_close(avctx);
-    return AVERROR(ENOMEM);
 }
 
 /**
@@ -496,6 +511,7 @@ static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb,
         x = (overflow << rice->k) + get_bits(gb, rice->k);
     } else {
         av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %"PRIu32"\n", rice->k);
+        ctx->error = 1;
         return AVERROR_INVALIDDATA;
     }
     rice->ksum += x - (rice->ksum + 8 >> 4);
@@ -544,12 +560,10 @@ static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice)
 
 static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice)
 {
-    unsigned int x, overflow;
-    int base, pivot;
+    unsigned int x, overflow, pivot;
+    int base;
 
-    pivot = rice->ksum >> 5;
-    if (pivot == 0)
-        pivot = 1;
+    pivot = FFMAX(rice->ksum >> 5, 1);
 
     overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
 
@@ -585,6 +599,11 @@ static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice)
     return ((x >> 1) ^ ((x & 1) - 1)) + 1;
 }
 
+static int get_k(int ksum)
+{
+    return av_log2(ksum) + !!ksum;
+}
+
 static void decode_array_0000(APEContext *ctx, GetBitContext *gb,
                               int32_t *out, APERice *rice, int blockstodecode)
 {
@@ -596,21 +615,34 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb,
         out[i] = get_rice_ook(&ctx->gb, 10);
         rice->ksum += out[i];
     }
-    rice->k = av_log2(rice->ksum / 10) + 1;
+
+    if (blockstodecode <= 5)
+        goto end;
+
+    rice->k = get_k(rice->ksum / 10);
     if (rice->k >= 24)
         return;
     for (; i < FFMIN(blockstodecode, 64); i++) {
         out[i] = get_rice_ook(&ctx->gb, rice->k);
         rice->ksum += out[i];
-        rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1;
+        rice->k = get_k(rice->ksum / ((i + 1) * 2));
         if (rice->k >= 24)
             return;
     }
+
+    if (blockstodecode <= 64)
+        goto end;
+
+    rice->k = get_k(rice->ksum >> 7);
     ksummax = 1 << rice->k + 7;
     ksummin = rice->k ? (1 << rice->k + 6) : 0;
     for (; i < blockstodecode; i++) {
+        if (get_bits_left(&ctx->gb) < 1) {
+            ctx->error = 1;
+            return;
+        }
         out[i] = get_rice_ook(&ctx->gb, rice->k);
-        rice->ksum += out[i] - out[i - 64];
+        rice->ksum += out[i] - (unsigned)out[i - 64];
         while (rice->ksum < ksummin) {
             rice->k--;
             ksummin = rice->k ? ksummin >> 1 : 0;
@@ -625,6 +657,7 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb,
         }
     }
 
+end:
     for (i = 0; i < blockstodecode; i++)
         out[i] = ((out[i] >> 1) ^ ((out[i] & 1) - 1)) + 1;
 }
@@ -730,6 +763,7 @@ static int init_entropy_decoder(APEContext *ctx)
 
     /* Read the frame flags if they exist */
     ctx->frameflags = 0;
+    ctx->CRC_state = UINT32_MAX;
     if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) {
         ctx->CRC &= ~0x80000000;
 
@@ -770,13 +804,20 @@ static const int32_t initial_coeffs_3930[4] = {
     360, 317, -109, 98
 };
 
+static const int64_t initial_coeffs_3930_64bit[4] = {
+    360, 317, -109, 98
+};
+
 static void init_predictor_decoder(APEContext *ctx)
 {
     APEPredictor *p = &ctx->predictor;
+    APEPredictor64 *p64 = &ctx->predictor64;
 
     /* Zero the history buffers */
     memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p->historybuffer));
+    memset(p64->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p64->historybuffer));
     p->buf = p->historybuffer;
+    p64->buf = p64->historybuffer;
 
     /* Initialize and zero the coefficients */
     if (ctx->fileversion < 3930) {
@@ -794,8 +835,11 @@ static void init_predictor_decoder(APEContext *ctx)
     } else {
         memcpy(p->coeffsA[0], initial_coeffs_3930, sizeof(initial_coeffs_3930));
         memcpy(p->coeffsA[1], initial_coeffs_3930, sizeof(initial_coeffs_3930));
+        memcpy(p64->coeffsA[0], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit));
+        memcpy(p64->coeffsA[1], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit));
     }
     memset(p->coeffsB, 0, sizeof(p->coeffsB));
+    memset(p64->coeffsB, 0, sizeof(p64->coeffsB));
     if (ctx->fileversion < 3930) {
         memcpy(p->coeffsB[0], initial_coeffs_b_3800,
                sizeof(initial_coeffs_b_3800));
@@ -807,7 +851,13 @@ static void init_predictor_decoder(APEContext *ctx)
     p->filterB[0] = p->filterB[1] = 0;
     p->lastA[0]   = p->lastA[1]   = 0;
 
+    p64->filterA[0] = p64->filterA[1] = 0;
+    p64->filterB[0] = p64->filterB[1] = 0;
+    p64->lastA[0]   = p64->lastA[1]   = 0;
+
     p->sample_pos = 0;
+
+    p64->sample_pos = 0;
 }
 
 /** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */
@@ -881,7 +931,7 @@ static av_always_inline int filter_3800(APEPredictor *p,
     p->coeffsB[filter][1] -= (((d4 >> 30) & 2) - 1) * sign;
 
     p->filterB[filter] = p->lastA[filter] + (predictionB >> shift);
-    p->filterA[filter] = p->filterB[filter] + ((int)(p->filterA[filter] * 31U) >> 5);
+    p->filterA[filter] = p->filterB[filter] + (unsigned)((int)(p->filterA[filter] * 31U) >> 5);
 
     return p->filterA[filter];
 }
@@ -916,7 +966,8 @@ static void long_filter_ehigh_3830(int32_t *buffer, int length)
 {
     int i, j;
     int32_t dotprod, sign;
-    int32_t coeffs[8] = { 0 }, delay[8] = { 0 };
+    int32_t delay[8] = { 0 };
+    uint32_t coeffs[8] = { 0 };
 
     for (i = 0; i < length; i++) {
         dotprod = 0;
@@ -1051,7 +1102,7 @@ static av_always_inline int predictor_update_3930(APEPredictor *p,
                   d3 * p->coeffsA[filter][3];
 
     p->lastA[filter] = decoded + (predictionA >> 9);
-    p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5);
+    p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5);
 
     sign = APESIGN(decoded);
     p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign;
@@ -1112,16 +1163,17 @@ static void predictor_decode_mono_3930(APEContext *ctx, int count)
     }
 }
 
-static av_always_inline int predictor_update_filter(APEPredictor *p,
+static av_always_inline int predictor_update_filter(APEPredictor64 *p,
                                                     const int decoded, const int filter,
                                                     const int delayA,  const int delayB,
                                                     const int adaptA,  const int adaptB)
 {
-    int32_t predictionA, predictionB, sign;
+    int64_t predictionA, predictionB;
+    int32_t sign;
 
     p->buf[delayA]     = p->lastA[filter];
     p->buf[adaptA]     = APESIGN(p->buf[delayA]);
-    p->buf[delayA - 1] = p->buf[delayA] - (unsigned)p->buf[delayA - 1];
+    p->buf[delayA - 1] = p->buf[delayA] - (uint64_t)p->buf[delayA - 1];
     p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]);
 
     predictionA = p->buf[delayA    ] * p->coeffsA[filter][0] +
@@ -1130,9 +1182,9 @@ static av_always_inline int predictor_update_filter(APEPredictor *p,
                   p->buf[delayA - 3] * p->coeffsA[filter][3];
 
     /*  Apply a scaled first-order filter compression */
-    p->buf[delayB]     = p->filterA[filter ^ 1] - ((int)(p->filterB[filter] * 31U) >> 5);
+    p->buf[delayB]     = p->filterA[filter ^ 1] - ((int64_t)(p->filterB[filter] * 31ULL) >> 5);
     p->buf[adaptB]     = APESIGN(p->buf[delayB]);
-    p->buf[delayB - 1] = p->buf[delayB] - (unsigned)p->buf[delayB - 1];
+    p->buf[delayB - 1] = p->buf[delayB] - (uint64_t)p->buf[delayB - 1];
     p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]);
     p->filterB[filter] = p->filterA[filter ^ 1];
 
@@ -1142,8 +1194,8 @@ static av_always_inline int predictor_update_filter(APEPredictor *p,
                   p->buf[delayB - 3] * p->coeffsB[filter][3] +
                   p->buf[delayB - 4] * p->coeffsB[filter][4];
 
-    p->lastA[filter] = decoded + ((int)((unsigned)predictionA + (predictionB >> 1)) >> 10);
-    p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5);
+    p->lastA[filter] = decoded + ((int64_t)((uint64_t)predictionA + (predictionB >> 1)) >> 10);
+    p->filterA[filter] = p->lastA[filter] + ((int64_t)(p->filterA[filter] * 31ULL) >> 5);
 
     sign = APESIGN(decoded);
     p->coeffsA[filter][0] += p->buf[adaptA    ] * sign;
@@ -1161,7 +1213,7 @@ static av_always_inline int predictor_update_filter(APEPredictor *p,
 
 static void predictor_decode_stereo_3950(APEContext *ctx, int count)
 {
-    APEPredictor *p = &ctx->predictor;
+    APEPredictor64 *p = &ctx->predictor64;
     int32_t *decoded0 = ctx->decoded[0];
     int32_t *decoded1 = ctx->decoded[1];
 
@@ -1190,7 +1242,7 @@ static void predictor_decode_stereo_3950(APEContext *ctx, int count)
 
 static void predictor_decode_mono_3950(APEContext *ctx, int count)
 {
-    APEPredictor *p = &ctx->predictor;
+    APEPredictor64 *p = &ctx->predictor64;
     int32_t *decoded0 = ctx->decoded[0];
     int32_t predictionA, currentA, A, sign;
 
@@ -1202,14 +1254,14 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count)
         A = *decoded0;
 
         p->buf[YDELAYA] = currentA;
-        p->buf[YDELAYA - 1] = p->buf[YDELAYA] - p->buf[YDELAYA - 1];
+        p->buf[YDELAYA - 1] = p->buf[YDELAYA] - (uint64_t)p->buf[YDELAYA - 1];
 
         predictionA = p->buf[YDELAYA    ] * p->coeffsA[0][0] +
                       p->buf[YDELAYA - 1] * p->coeffsA[0][1] +
                       p->buf[YDELAYA - 2] * p->coeffsA[0][2] +
                       p->buf[YDELAYA - 3] * p->coeffsA[0][3];
 
-        currentA = A + (predictionA >> 10);
+        currentA = A + (uint64_t)(predictionA >> 10);
 
         p->buf[YADAPTCOEFFSA]     = APESIGN(p->buf[YDELAYA    ]);
         p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]);
@@ -1229,7 +1281,7 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count)
             p->buf = p->historybuffer;
         }
 
-        p->filterA[0] = currentA + ((int)(p->filterA[0] * 31U) >> 5);
+        p->filterA[0] = currentA + (uint64_t)((int64_t)(p->filterA[0] * 31U) >> 5);
         *(decoded0++) = p->filterA[0];
     }
 
@@ -1258,7 +1310,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,
                             int32_t *data, int count, int order, int fracbits)
 {
     int res;
-    int absres;
+    unsigned absres;
 
     while (count--) {
         /* round fixedpoint scalar product */
@@ -1266,8 +1318,8 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,
                                                      f->delay - order,
                                                      f->adaptcoeffs - order,
                                                      order, APESIGN(*data));
-        res = (int)(res + (1U << (fracbits - 1))) >> fracbits;
-        res += *data;
+        res = (int64_t)(res + (1LL << (fracbits - 1))) >> fracbits;
+        res += (unsigned)*data;
         *data++ = res;
 
         /* Update the output history */
@@ -1282,7 +1334,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,
             /* Version 3.98 and later files */
 
             /* Update the adaption coefficients */
-            absres = res < 0 ? -(unsigned)res : res;
+            absres = FFABSU(res);
             if (absres)
                 *f->adaptcoeffs = APESIGN(res) *
                                   (8 << ((absres > f->avg * 3) + (absres > f->avg * 4 / 3)));
@@ -1297,7 +1349,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,
             else
                 *f->adaptcoeffs = 0;
 
-            f->avg += (absres - f->avg) / 16;
+            f->avg += (int)(absres - (unsigned)f->avg) / 16;
 
             f->adaptcoeffs[-1] >>= 1;
             f->adaptcoeffs[-2] >>= 1;
@@ -1512,7 +1564,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     av_fast_malloc(&s->decoded_buffer, &s->decoded_size, decoded_buffer_size);
     if (!s->decoded_buffer)
         return AVERROR(ENOMEM);
-    memset(s->decoded_buffer, 0, s->decoded_size);
+    memset(s->decoded_buffer, 0, decoded_buffer_size);
     s->decoded[0] = s->decoded_buffer;
     s->decoded[1] = s->decoded_buffer + FFALIGN(blockstodecode, 8);
 
@@ -1549,13 +1601,34 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
         for (ch = 0; ch < s->channels; ch++) {
             sample24 = (int32_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
-                *sample24++ = s->decoded[ch][i] << 8;
+                *sample24++ = s->decoded[ch][i] * 256U;
         }
         break;
     }
 
     s->samples -= blockstodecode;
 
+    if (avctx->err_recognition & AV_EF_CRCCHECK &&
+        s->fileversion >= 3900 && s->bps < 24) {
+        uint32_t crc = s->CRC_state;
+        const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE);
+        for (i = 0; i < blockstodecode; i++) {
+            for (ch = 0; ch < s->channels; ch++) {
+                uint8_t *smp = frame->data[ch] + (i*(s->bps >> 3));
+                crc = av_crc(crc_tab, crc, smp, s->bps >> 3);
+            }
+        }
+
+        if (!s->samples && (~crc >> 1) ^ s->CRC) {
+            av_log(avctx, AV_LOG_ERROR, "CRC mismatch! Previously decoded "
+                   "frames may have been affected as well.\n");
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
+        }
+
+        s->CRC_state = crc;
+    }
+
     *got_frame_ptr = 1;
 
     return !s->samples ? avpkt->size : 0;
@@ -1582,7 +1655,7 @@ static const AVClass ape_decoder_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-AVCodec ff_ape_decoder = {
+const AVCodec ff_ape_decoder = {
     .name           = "ape",
     .long_name      = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -1593,6 +1666,7 @@ AVCodec ff_ape_decoder = {
     .decode         = ape_decode_frame,
     .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
                       AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .flush          = ape_flush,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                       AV_SAMPLE_FMT_S16P,