summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2019-03-06 17:04:04 +0000
committerLynne <dev@lynne.ee>2020-05-26 10:23:11 +0100
commite69f407b52110387800ee0531aa78e213b214150 (patch)
tree7160f050b15527bafcfd570f0c5845ffe1ef3ffa
parent1cc8eecd3844ede71224edcbdd67ebca505146ba (diff)
mpegaudiodec_template: add ability to check CRC
A lot of files have CRC included. The CRC only covers 34 bytes at most from the frame but it should still be enough for some amount of error detection.
-rw-r--r--libavcodec/mpegaudiodec_template.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
index 3f1674e827..3d7e3ba4f2 100644
--- a/libavcodec/mpegaudiodec_template.c
+++ b/libavcodec/mpegaudiodec_template.c
@@ -27,6 +27,7 @@
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
+#include "libavutil/crc.h"
#include "libavutil/float_dsp.h"
#include "libavutil/libm.h"
#include "avcodec.h"
@@ -1565,9 +1566,22 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
- /* skip error protection field */
- if (s->error_protection)
- skip_bits(&s->gb, 16);
+ if (s->error_protection) {
+ uint16_t crc = get_bits(&s->gb, 16);
+ if (s->err_recognition & AV_EF_CRCCHECK) {
+ const int sec_len = s->lsf ? ((s->nb_channels == 1) ? 9 : 17) :
+ ((s->nb_channels == 1) ? 17 : 32);
+ const AVCRC *crc_tab = av_crc_get_table(AV_CRC_16_ANSI);
+ uint32_t crc_cal = av_crc(crc_tab, UINT16_MAX, &buf[2], 2);
+ crc_cal = av_crc(crc_tab, crc_cal, &buf[6], sec_len);
+
+ if (av_bswap16(crc) ^ crc_cal) {
+ av_log(s->avctx, AV_LOG_ERROR, "CRC mismatch!\n");
+ if (s->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
switch(s->layer) {
case 1: