avcodec/dca: convert to AVCRC
authorfoo86 <foobaz86@gmail.com>
Tue, 3 May 2016 00:42:36 +0000 (03:42 +0300)
committerJames Almer <jamrial@gmail.com>
Tue, 3 May 2016 19:40:43 +0000 (16:40 -0300)
Signed-off-by: James Almer <jamrial@gmail.com>
libavcodec/dca_core.c
libavcodec/dca_exss.c
libavcodec/dca_xll.c
libavcodec/dcadec.c
libavcodec/dcadec.h

index 58c78f7..f6c22ca 100644 (file)
@@ -269,8 +269,7 @@ static int parse_coding_header(DCACoreDecoder *s, enum HeaderType header, int xc
 
         // Check CRC
         if (s->xxch_crc_present
-            && (s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-            && ff_dca_check_crc(&s->gb, header_pos, header_pos + header_size * 8)) {
+            && ff_dca_check_crc(s->avctx, &s->gb, header_pos, header_pos + header_size * 8)) {
             av_log(s->avctx, AV_LOG_ERROR, "Invalid XXCH channel set header checksum\n");
             return AVERROR_INVALIDDATA;
         }
@@ -977,8 +976,7 @@ static int parse_xxch_frame(DCACoreDecoder *s)
     header_size = get_bits(&s->gb, 6) + 1;
 
     // Check XXCH frame header CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, header_pos + 32, header_pos + header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, header_pos + 32, header_pos + header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid XXCH frame header checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -1193,8 +1191,7 @@ static int parse_xbr_frame(DCACoreDecoder *s)
     header_size = get_bits(&s->gb, 6) + 1;
 
     // Check XBR frame header CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, header_pos + 32, header_pos + header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, header_pos + 32, header_pos + header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid XBR frame header checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -1509,8 +1506,7 @@ static int parse_x96_coding_header(DCACoreDecoder *s, int exss, int xch_base)
 
         // Check CRC
         if (s->x96_crc_present
-            && (s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-            && ff_dca_check_crc(&s->gb, header_pos, header_pos + header_size * 8)) {
+            && ff_dca_check_crc(s->avctx, &s->gb, header_pos, header_pos + header_size * 8)) {
             av_log(s->avctx, AV_LOG_ERROR, "Invalid X96 channel set header checksum\n");
             return AVERROR_INVALIDDATA;
         }
@@ -1665,8 +1661,7 @@ static int parse_x96_frame_exss(DCACoreDecoder *s)
     header_size = get_bits(&s->gb, 6) + 1;
 
     // Check X96 frame header CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, header_pos + 32, header_pos + header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, header_pos + 32, header_pos + header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid X96 frame header checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -1785,8 +1780,7 @@ static int parse_aux_data(DCACoreDecoder *s)
     skip_bits(&s->gb, 16);
 
     // Check CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, aux_pos, get_bits_count(&s->gb))) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, aux_pos, get_bits_count(&s->gb))) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid auxiliary data checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -1884,9 +1878,10 @@ static int parse_optional_info(DCACoreDecoder *s)
                 if (AV_RB32(s->gb.buffer + sync_pos * 4) == DCA_SYNCWORD_XXCH) {
                     s->gb.index = (sync_pos + 1) * 32;
                     size = get_bits(&s->gb, 6) + 1;
-                    if (size >= 11 &&
-                        !ff_dca_check_crc(&s->gb, (sync_pos + 1) * 32,
-                                          sync_pos * 32 + size * 8)) {
+                    dist = s->gb.size_in_bits / 8 - sync_pos * 4;
+                    if (size >= 11 && size <= dist &&
+                        !av_crc(dca->crctab, 0xffff, s->gb.buffer +
+                                (sync_pos + 1) * 4, size - 4)) {
                         s->xxch_pos = sync_pos * 32;
                         break;
                     }
index 36314c2..87b2f42 100644 (file)
@@ -398,8 +398,7 @@ int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size)
     header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1;
 
     // Check CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, 32 + 8, header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, 32 + 8, header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n");
         return AVERROR_INVALIDDATA;
     }
index 5e6cf35..316af27 100644 (file)
@@ -123,8 +123,7 @@ static int chs_parse_header(DCAXllDecoder *s, DCAXllChSet *c, DCAExssAsset *asse
     header_size = get_bits(&s->gb, 10) + 1;
 
     // Check CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, header_pos, header_pos + header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, header_pos, header_pos + header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid XLL sub-header checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -784,8 +783,7 @@ static int parse_common_header(DCAXllDecoder *s)
     header_size = get_bits(&s->gb, 8) + 1;
 
     // Check CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, 32, header_size * 8)) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, 32, header_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid XLL common header checksum\n");
         return AVERROR_INVALIDDATA;
     }
@@ -993,8 +991,7 @@ static int parse_navi_table(DCAXllDecoder *s)
     skip_bits(&s->gb, 16);
 
     // Check CRC
-    if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
-        && ff_dca_check_crc(&s->gb, navi_pos, get_bits_count(&s->gb))) {
+    if (ff_dca_check_crc(s->avctx, &s->gb, navi_pos, get_bits_count(&s->gb))) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid NAVI checksum\n");
         return AVERROR_INVALIDDATA;
     }
index 92c2334..f5ddc21 100644 (file)
@@ -76,33 +76,6 @@ int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask
     return nchannels;
 }
 
-static uint16_t crc16(const uint8_t *data, int size)
-{
-    static const uint16_t crctab[16] = {
-        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
-        0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
-    };
-
-    uint16_t res = 0xffff;
-    int i;
-
-    for (i = 0; i < size; i++) {
-        res = (res << 4) ^ crctab[(data[i] >> 4) ^ (res >> 12)];
-        res = (res << 4) ^ crctab[(data[i] & 15) ^ (res >> 12)];
-    }
-
-    return res;
-}
-
-int ff_dca_check_crc(GetBitContext *s, int p1, int p2)
-{
-    if (((p1 | p2) & 7) || p1 < 0 || p2 > s->size_in_bits || p2 - p1 < 16)
-        return -1;
-    if (crc16(s->buffer + p1 / 8, (p2 - p1) / 8))
-        return -1;
-    return 0;
-}
-
 void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples,
                                     int *coeff_l, int nsamples, int ch_mask)
 {
@@ -359,6 +332,8 @@ static av_cold int dcadec_init(AVCodecContext *avctx)
     s->core.dcadsp = &s->dcadsp;
     s->xll.dcadsp = &s->dcadsp;
 
+    s->crctab = av_crc_get_table(AV_CRC_16_CCITT);
+
     switch (avctx->request_channel_layout & ~AV_CH_LAYOUT_NATIVE) {
     case 0:
         s->request_channel_layout = 0;
index 6726121..0d8a145 100644 (file)
@@ -22,6 +22,7 @@
 #define AVCODEC_DCADEC_H
 
 #include "libavutil/common.h"
+#include "libavutil/crc.h"
 #include "libavutil/float_dsp.h"
 
 #include "avcodec.h"
@@ -49,6 +50,8 @@ typedef struct DCAContext {
 
     DCADSPContext   dcadsp;
 
+    const AVCRC     *crctab;
+
     uint8_t         *buffer;    ///< Packet buffer
     unsigned int    buffer_size;
 
@@ -62,13 +65,25 @@ typedef struct DCAContext {
 
 int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask);
 
-int ff_dca_check_crc(GetBitContext *s, int p1, int p2);
-
 void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples,
                                     int *coeff_l, int nsamples, int ch_mask);
 void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples,
                                     int *coeff_l, int nsamples, int ch_mask);
 
+static inline int ff_dca_check_crc(AVCodecContext *avctx, GetBitContext *s,
+                                   int p1, int p2)
+{
+    DCAContext *dca = avctx->priv_data;
+
+    if (!(avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL)))
+        return 0;
+    if (((p1 | p2) & 7) || p1 < 0 || p2 > s->size_in_bits || p2 - p1 < 16)
+        return -1;
+    if (av_crc(dca->crctab, 0xffff, s->buffer + p1 / 8, (p2 - p1) / 8))
+        return -1;
+    return 0;
+}
+
 static inline int ff_dca_seek_bits(GetBitContext *s, int p)
 {
     if (p < s->index || p > s->size_in_bits)