|
|
@@ -24,6 +24,7 @@ |
|
|
|
|
|
|
|
|
#include "libavutil/avassert.h" |
|
|
#include "libavutil/avassert.h" |
|
|
#include "libavutil/channel_layout.h" |
|
|
#include "libavutil/channel_layout.h" |
|
|
|
|
|
#include "libavutil/crc.h" |
|
|
#include "libavutil/opt.h" |
|
|
#include "libavutil/opt.h" |
|
|
#include "lossless_audiodsp.h" |
|
|
#include "lossless_audiodsp.h" |
|
|
#include "avcodec.h" |
|
|
#include "avcodec.h" |
|
|
@@ -147,7 +148,8 @@ typedef struct APEContext { |
|
|
int fset; ///< which filter set to use (calculated from compression level) |
|
|
int fset; ///< which filter set to use (calculated from compression level) |
|
|
int flags; ///< global decoder flags |
|
|
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 |
|
|
int frameflags; ///< frame flags |
|
|
APEPredictor predictor; ///< predictor used for final reconstruction |
|
|
APEPredictor predictor; ///< predictor used for final reconstruction |
|
|
|
|
|
|
|
|
@@ -750,6 +752,7 @@ static int init_entropy_decoder(APEContext *ctx) |
|
|
|
|
|
|
|
|
/* Read the frame flags if they exist */ |
|
|
/* Read the frame flags if they exist */ |
|
|
ctx->frameflags = 0; |
|
|
ctx->frameflags = 0; |
|
|
|
|
|
ctx->CRC_state = UINT32_MAX; |
|
|
if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) { |
|
|
if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) { |
|
|
ctx->CRC &= ~0x80000000; |
|
|
ctx->CRC &= ~0x80000000; |
|
|
|
|
|
|
|
|
@@ -1577,6 +1580,27 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
|
s->samples -= blockstodecode; |
|
|
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; |
|
|
*got_frame_ptr = 1; |
|
|
|
|
|
|
|
|
return !s->samples ? avpkt->size : 0; |
|
|
return !s->samples ? avpkt->size : 0; |
|
|
|