| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (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 | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with FFmpeg; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <assert.h> | ||
| 20 | #include <stddef.h> | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdlib.h> | ||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | #include "checkasm.h" | ||
| 26 | #include "libavutil/attributes.h" | ||
| 27 | // Undefine av_pure so that calls to av_crc are not optimized away. | ||
| 28 | #undef av_pure | ||
| 29 | #define av_pure | ||
| 30 | #include "libavutil/avassert.h" | ||
| 31 | #include "libavutil/crc.h" | ||
| 32 | #include "libavutil/intreadwrite.h" | ||
| 33 | #include "libavutil/macros.h" | ||
| 34 | #include "libavutil/mem_internal.h" | ||
| 35 | |||
| 36 | |||
| 37 | 126 | static void check_crc(const AVCRC *table_new, const char *name, unsigned idx) | |
| 38 | { | ||
| 39 | 126 | declare_func(uint32_t, const AVCRC *ctx, uint32_t crc, | |
| 40 | const uint8_t *buffer, size_t length); | ||
| 41 | 126 | const AVCRC *table_ref = check_key((AVCRC*)table_new, "crc_%s", name); | |
| 42 | |||
| 43 |
2/2✓ Branch 0 taken 108 times.
✓ Branch 1 taken 18 times.
|
126 | if (!table_ref) |
| 44 | 108 | return; | |
| 45 | |||
| 46 | DECLARE_ALIGNED(4, uint8_t, buf)[8192]; | ||
| 47 | 18 | size_t offset = rnd() & 31; | |
| 48 | static size_t sizes[AV_CRC_MAX + 1]; | ||
| 49 | static unsigned sizes_initialized = 0; | ||
| 50 | 18 | uint32_t prev_crc = rnd(); | |
| 51 | |||
| 52 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
|
18 | if (!(sizes_initialized & (1 << idx))) { |
| 53 | 9 | sizes_initialized |= 1 << idx; | |
| 54 | 9 | sizes[idx] = rnd() % (sizeof(buf) - 1 - offset); | |
| 55 | } | ||
| 56 | |||
| 57 | 18 | size_t size = sizes[idx]; | |
| 58 | |||
| 59 |
2/2✓ Branch 0 taken 36864 times.
✓ Branch 1 taken 18 times.
|
36882 | for (size_t j = 0; j < sizeof(buf); j += 4) |
| 60 | 36864 | AV_WN32A(buf + j, rnd()); | |
| 61 | |||
| 62 | 18 | uint32_t crc_ref = checkasm_call (av_crc, table_ref, prev_crc, buf + offset, size); | |
| 63 | 18 | uint32_t crc_new = checkasm_call_checked(av_crc, table_new, prev_crc, buf + offset, size); | |
| 64 | |||
| 65 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | if (crc_ref != crc_new) |
| 66 | ✗ | fail(); | |
| 67 | |||
| 68 |
1/8✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
|
18 | bench(av_crc, table_new, prev_crc, buf + offset, size); |
| 69 | } | ||
| 70 | |||
| 71 | 14 | void checkasm_check_crc(void) | |
| 72 | { | ||
| 73 | static const char *const tests[] = { | ||
| 74 | #define TEST(CRC) [AV_CRC_ ## CRC] = #CRC | ||
| 75 | TEST(8_ATM), TEST(8_EBU), | ||
| 76 | TEST(16_ANSI), TEST(16_ANSI_LE), TEST(16_CCITT), | ||
| 77 | TEST(24_IEEE), TEST(32_IEEE_LE), TEST(32_IEEE), | ||
| 78 | }; | ||
| 79 | static_assert(FF_ARRAY_ELEMS(tests) == AV_CRC_MAX, "test needs to be added"); | ||
| 80 | |||
| 81 |
2/2✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14 times.
|
126 | for (unsigned i = 0; i < AV_CRC_MAX; ++i) |
| 82 | 112 | check_crc(av_crc_get_table(i), tests[i], i); | |
| 83 | |||
| 84 | static struct CustomTest { | ||
| 85 | struct CustomTest *prev; | ||
| 86 | AVCRC ctx[1024]; | ||
| 87 | } *ctx = NULL; | ||
| 88 | 14 | struct CustomTest *new = malloc(sizeof(*new)); | |
| 89 | static int le, bits; | ||
| 90 | static uint32_t poly; | ||
| 91 | |||
| 92 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (!new) |
| 93 | ✗ | fail(); | |
| 94 | |||
| 95 | 14 | memset(new, 0, sizeof(*new)); | |
| 96 | |||
| 97 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if (!ctx) { |
| 98 | 1 | le = rnd() & 1; | |
| 99 | 1 | bits = 8 + rnd() % 25; // av_crc_init() accepts between 8 and 32 bits | |
| 100 | 1 | poly = rnd() >> (32 - bits); | |
| 101 | } | ||
| 102 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
14 | av_assert0(av_crc_init(new->ctx, le, bits, poly, sizeof(new->ctx)) >= 0); |
| 103 |
4/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1 times.
|
14 | if (ctx && !memcmp(ctx->ctx, new->ctx, sizeof(new->ctx))) { |
| 104 | 12 | free(new); | |
| 105 | } else { | ||
| 106 | 2 | new->prev = ctx; | |
| 107 | 2 | ctx = new; | |
| 108 | } | ||
| 109 | |||
| 110 | 14 | check_crc(ctx->ctx, "custom_polynomial", AV_CRC_MAX); | |
| 111 | 14 | report("crc"); | |
| 112 | 14 | } | |
| 113 |