summaryrefslogtreecommitdiff
path: root/libavcodec/mpegaudiodec_template.c
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 /libavcodec/mpegaudiodec_template.c
parent1cc8eecd3844ede71224edcbdd67ebca505146ba (diff)
downloadffmpeg-e69f407b52110387800ee0531aa78e213b214150.tar.gz
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.
Diffstat (limited to 'libavcodec/mpegaudiodec_template.c')
-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: