FFmpeg
Loading...
Searching...
No Matches
crc.h
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef AVUTIL_AARCH64_CRC_H
20#define AVUTIL_AARCH64_CRC_H
21
22#include <stddef.h>
23#include <stdint.h>
24
25#include "config.h"
26
27#include "cpu.h"
29#include "libavutil/avassert.h"
30#include "libavutil/cpu.h"
31#include "libavutil/crc.h"
33
34#if HAVE_ARM_CRC
36uint32_t ff_crc32_aarch64(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer,
37 size_t length);
39#endif
40
41#if HAVE_PMULL && HAVE_EOR3
43
45uint32_t ff_crc_neon_pmull(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer,
46 size_t length);
47uint32_t ff_crc_le_neon_pmull(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer,
48 size_t length);
50
51enum {
52 CRC_C = 0,
53 PMULL_BE,
54 PMULL_LE,
55 CRC32_PMULL_LE,
56};
57
58static const AVCRC crc_table_pmull[AV_CRC_MAX][17] = {
59 [AV_CRC_8_ATM] = {
60 PMULL_BE,
61 0xbc000000, 0x0, 0x32000000, 0x0,
62 0x94000000, 0x0, 0xc4000000, 0x0,
63 0x62000000, 0x0, 0x79000000, 0x0,
64 0x07156a16, 0x1, 0x07000000, 0x1,
65 },
66 [AV_CRC_8_EBU] = {
67 PMULL_BE,
68 0xf3000000, 0x0, 0xb5000000, 0x0,
69 0x0d000000, 0x0, 0xfc000000, 0x0,
70 0x6a000000, 0x0, 0x65000000, 0x0,
71 0x1c4b8192, 0x1, 0x1d000000, 0x1,
72 },
73 [AV_CRC_16_ANSI] = {
74 PMULL_BE,
75 0x807d0000, 0x0, 0xf9e30000, 0x0,
76 0xff830000, 0x0, 0xf9130000, 0x0,
77 0x807b0000, 0x0, 0x86630000, 0x0,
78 0xfffbffe7, 0x1, 0x80050000, 0x1,
79 },
80 [AV_CRC_16_CCITT] = {
81 PMULL_BE,
82 0x59b00000, 0x0, 0x60190000, 0x0,
83 0x45630000, 0x0, 0xd5f60000, 0x0,
84 0xaa510000, 0x0, 0xeb230000, 0x0,
85 0x11303471, 0x1, 0x10210000, 0x1,
86 },
87 [AV_CRC_24_IEEE] = {
88 PMULL_BE,
89 0x467d2400, 0x0, 0x1f428700, 0x0,
90 0x64e4d700, 0x0, 0x2c8c9d00, 0x0,
91 0xd9fe8c00, 0x0, 0xfd7e0c00, 0x0,
92 0xf845fe24, 0x1, 0x864cfb00, 0x1,
93 },
94 [AV_CRC_32_IEEE] = {
95 PMULL_BE,
96 0xe6228b11, 0x0, 0x8833794c, 0x0,
97 0xe8a45605, 0x0, 0xc5b9cd4c, 0x0,
98 0x490d678d, 0x0, 0xf200aa66, 0x0,
99 0x04d101df, 0x1, 0x04c11db7, 0x1,
100 },
102 PMULL_LE,
103 0x54442bd4, 0x1, 0xc6e41596, 0x1,
104 0x751997d0, 0x1, 0xccaa009e, 0x0,
105 0xccaa009e, 0x0, 0x63cd6124, 0x1,
106 0xf7011640, 0x1, 0xdb710641, 0x1,
107 },
109 PMULL_LE,
110 0x1b0c2, 0x0, 0x0000bffa, 0x0,
111 0x1d0c2, 0x0, 0x00018cc2, 0x0,
112 0x00018cc2, 0x0, 0x1bc02, 0x0,
113 0xcfffbffe, 0x1, 0x14003, 0x0,
114 },
115};
116
117
118static inline void crc_init_aarch64(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
119{
120 uint64_t poly_;
121 if (le) {
122 // convert the reversed representation to regular form
123 poly = reverse(poly, bits) >> 1;
124 }
125 // convert to 32 degree polynomial
126 poly_ = ((uint64_t)poly) << (32 - bits);
127
128 uint64_t div;
129 uint8_t *dst = (uint8_t*)(ctx + 1);
130 if (le) {
131 ctx[0] = PMULL_LE;
132 AV_WN64(dst + 0, xnmodp(4 * 128 + 32, poly_, 32, &div, le));
133 AV_WN64(dst + 8, xnmodp(4 * 128 - 32, poly_, 32, &div, le));
134 uint64_t tmp = xnmodp(128 - 32, poly_, 32, &div, le);
135 AV_WN64(dst + 16, xnmodp(128 + 32, poly_, 32, &div, le));
136 AV_WN64(dst + 24, tmp);
137 AV_WN64(dst + 32, tmp);
138 AV_WN64(dst + 40, xnmodp(64, poly_, 32, &div, le));
139 AV_WN64(dst + 48, div);
140 AV_WN64(dst + 56, reverse(poly_ | (1ULL << 32), 32));
141 } else {
142 ctx[0] = PMULL_BE;
143 AV_WN64(dst + 0, xnmodp(4 * 128, poly_, 32, &div, le));
144 AV_WN64(dst + 8, xnmodp(4 * 128 + 64, poly_, 32, &div, le));
145 AV_WN64(dst + 16, xnmodp(128, poly_, 32, &div, le));
146 AV_WN64(dst + 24, xnmodp(128 + 64, poly_, 32, &div, le));
147 AV_WN64(dst + 32, xnmodp(64, poly_, 32, &div, le));
148 AV_WN64(dst + 48, div);
149 AV_WN64(dst + 40, xnmodp(96, poly_, 32, &div, le));
150 AV_WN64(dst + 56, poly_ | (1ULL << 32));
151 }
152}
153
154#if HAVE_ARM_CRC
156uint32_t ff_crc32_pmull_eor3_aarch64(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer,
157 size_t length);
159static const AVCRC crc_table_crc32_pmull[] = {
160 CRC32_PMULL_LE,
161 0x26b70c3d, 0x0, 0x3f41287a, 0x0,
162 0xae689191, 0x0, 0xccaa009e, 0x0,
163 0xf1da05aa, 0x0, 0x81256527, 0x0,
164 0x8f352d95, 0x0, 0x1d9513d7, 0x0,
165 0x54442bd4, 0x1, 0xc6e41596, 0x1,
166 0x751997d0, 0x1, 0xccaa009e, 0x0,
167 0xccaa009e, 0x0, 0x63cd6124, 0x1,
168 0xf7011640, 0x1, 0xdb710641, 0x1,
169};
170#endif
171#endif
172
173static inline av_cold int ff_crc_init_aarch64(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
174{
175#if HAVE_PMULL && HAVE_EOR3
177
179 crc_init_aarch64(ctx, le, bits, poly, ctx_size);
180 return 1;
181 }
182#endif
183 return 0;
184}
185
186static inline uint32_t ff_crc_aarch64(const AVCRC *ctx, uint32_t crc,
187 const uint8_t *buffer, size_t length)
188{
189 switch (ctx[0]) {
190#if HAVE_PMULL && HAVE_EOR3
191#if HAVE_ARM_CRC
192 case CRC32_PMULL_LE: return ff_crc32_pmull_eor3_aarch64(ctx, crc, buffer, length);
193#endif
194 case PMULL_BE: return ff_crc_neon_pmull(ctx, crc, buffer, length);
195 case PMULL_LE: return ff_crc_le_neon_pmull(ctx, crc, buffer, length);
196#endif
197#if HAVE_ARM_CRC
198 case (AV_CRC_32_IEEE_LE + 1): return ff_crc32_aarch64(ctx, crc, buffer, length);
199#endif
200 default: av_unreachable("AARCH64 has PMULL_LE, PMULL_BE, CRC32_PMULL_LE, and AV_CRC_32_IEEE_LE arch-specific CRC code");
201 }
202 return 0;
203}
204
205static inline const AVCRC *ff_crc_get_table_aarch64(AVCRCId crc_id)
206{
208#if HAVE_PMULL && HAVE_EOR3
210#if HAVE_ARM_CRC
211 if (crc_id == AV_CRC_32_IEEE_LE && have_arm_crc(cpu_flags)) {
212 return crc_table_crc32_pmull;
213 }
214#endif
215 return crc_table_pmull[crc_id];
216 }
217#endif
218#if HAVE_ARM_CRC
219 static const AVCRC crc32_ieee_le_ctx[] = {
221 };
222
223 if (crc_id != AV_CRC_32_IEEE_LE)
224 return NULL;
225
226 if (have_arm_crc(cpu_flags)) {
227 return crc32_ieee_le_ctx;
228 }
229#endif
230 return NULL;
231}
232
233#endif /* AVUTIL_AARCH64_CRC_H */
static uint32_t ff_crc_aarch64(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Definition crc.h:186
static const AVCRC * ff_crc_get_table_aarch64(AVCRCId crc_id)
Definition crc.h:205
static av_cold int ff_crc_init_aarch64(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
Definition crc.h:173
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static AVFormatContext * ctx
#define FF_VISIBILITY_PUSH_HIDDEN
#define FF_VISIBILITY_POP_HIDDEN
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#define NULL
Definition coverity.c:32
Public header for CRC hash function implementation.
static av_unused uint64_t xnmodp(unsigned n, uint64_t poly, unsigned deg, uint64_t *div, int bitreverse)
static uint64_t reverse(uint64_t p, unsigned int deg)
static const uint8_t bits[8]
Definition fastaudio.c:100
AVCRCId
Definition crc.h:48
uint32_t AVCRC
Definition crc.h:46
@ AV_CRC_16_CCITT
Definition crc.h:51
@ AV_CRC_32_IEEE
Definition crc.h:52
@ AV_CRC_24_IEEE
Definition crc.h:55
@ AV_CRC_8_EBU
Definition crc.h:56
@ AV_CRC_8_ATM
Definition crc.h:49
@ AV_CRC_32_IEEE_LE
Definition crc.h:53
@ AV_CRC_MAX
Definition crc.h:57
@ AV_CRC_16_ANSI
Definition crc.h:50
@ AV_CRC_16_ANSI_LE
Definition crc.h:54
#define AV_WN64(p, v)
#define have_pmull(flags)
Definition cpu.h:29
#define have_arm_crc(flags)
Definition cpu.h:28
#define have_eor3(flags)
Definition cpu.h:30
#define av_cold
Definition attributes.h:117
static atomic_int cpu_flags
Definition cpu.c:56
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition cpu.c:109
static uint8_t tmp[40]
Definition aes_ctr.c:52
static char buffer[20]
Definition seek.c:32