FFmpeg
Loading...
Searching...
No Matches
cavsdsp.c
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/*
20 * Check the C inverse transform against the matrix product of
21 * GB/T 20090.2-2013 9.8.2 and GY/T 257.1-2012 9.7.
22 * The SIMD versions are checked against the C version by checkasm.
23 */
24
25#include <stdint.h>
26#include <stdio.h>
27#include <string.h>
28
29#include "libavutil/common.h"
30#include "libavutil/cpu.h"
31#include "libavutil/lfg.h"
33
34#include "libavcodec/cavsdsp.h"
35#include "libavcodec/idctdsp.h"
36
37#define STRIDE 16
38
39static const int8_t t8[8][8] = {
40 { 8, 10, 10, 9, 8, 6, 4, 2 },
41 { 8, 9, 4, -2, -8, -10, -10, -6 },
42 { 8, 6, -4, -10, -8, 2, 10, 9 },
43 { 8, 2, -10, -6, 8, 9, -4, -10 },
44 { 8, -2, -10, 6, 8, -9, -4, 10 },
45 { 8, -6, -4, 10, -8, -2, 10, -9 },
46 { 8, -9, 4, 2, -8, 10, -10, 6 },
47 { 8, -10, 10, -9, 8, -6, 4, -2 },
48};
49
50static void idct8_add_ref(uint8_t *dst, const int16_t coeffs[64])
51{
52 int tmp[8][8];
53
54 for (int i = 0; i < 8; i++) {
55 for (int j = 0; j < 8; j++) {
56 int sum = 4;
57 for (int k = 0; k < 8; k++)
58 sum += coeffs[8 * i + k] * t8[j][k];
59 tmp[i][j] = av_clip_int16(sum) >> 3;
60 }
61 }
62 for (int i = 0; i < 8; i++) {
63 for (int j = 0; j < 8; j++) {
64 int sum = 64;
65 for (int k = 0; k < 8; k++)
66 sum += t8[i][k] * tmp[k][j];
67 dst[j] = av_clip_uint8(dst[j] + (av_clip_int16(sum) >> 7));
68 }
69 dst += STRIDE;
70 }
71}
72
73static int check_block(CAVSDSPContext *c, const uint8_t *perm,
74 const int16_t coeffs[64], AVLFG *lfg, int n)
75{
76 DECLARE_ALIGNED(16, int16_t, block)[64];
77 DECLARE_ALIGNED(16, uint8_t, ref)[8 * STRIDE];
78 DECLARE_ALIGNED(16, uint8_t, out)[8 * STRIDE];
79
80 for (int i = 0; i < 64; i++)
81 block[perm[i]] = coeffs[i];
82 for (int i = 0; i < 8 * STRIDE; i++)
83 ref[i] = out[i] = av_lfg_get(lfg);
84
85 idct8_add_ref(ref, coeffs);
86 c->cavs_idct8_add(out, block, STRIDE);
87 if (memcmp(ref, out, sizeof(ref))) {
88 fprintf(stderr, "cavs_idct8_add: mismatch in block %d\n", n);
89 return 1;
90 }
91 return 0;
92}
93
94int main(void)
95{
97 uint8_t perm[64];
98 int16_t coeffs[64];
99 AVLFG lfg;
100 int n = 0, ret = 0;
101
105 av_lfg_init(&lfg, 1);
106
107 /* drive each first pass sum to both ends of its range */
108 for (int j = 0; j < 8; j++) {
109 for (int sign = -1; sign <= 1; sign += 2) {
110 for (int i = 0; i < 64; i++)
111 coeffs[i] = (t8[j][i & 7] * sign < 0) ? INT16_MIN : INT16_MAX;
112 ret |= check_block(&c, perm, coeffs, &lfg, n++);
113 }
114 }
115
116 /* magnitudes from the whole int16_t range down to single digits */
117 for (int iter = 0; iter < 100000; iter++) {
118 int count = 1 + av_lfg_get(&lfg) % 64;
119
120 memset(coeffs, 0, sizeof(coeffs));
121 for (int k = 0; k < count; k++) {
122 unsigned r = av_lfg_get(&lfg);
123 coeffs[r & 63] = (int16_t)av_lfg_get(&lfg) >> (r >> 6 & 15);
124 }
125 ret |= check_block(&c, perm, coeffs, &lfg, n++);
126 }
127
128 return ret;
129}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
static FILE * out
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
common internal and external API header
#define av_clip_int16
Definition common.h:115
#define av_clip_uint8
Definition common.h:106
static int16_t block[64]
Definition dct.c:125
perm
Definition f_perms.c:75
int ret
Definition ffplay.c:391
#define r
Definition input.c:42
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition lfg.c:32
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition lfg.h:53
av_cold void ff_cavsdsp_init(CAVSDSPContext *c)
Definition cavsdsp.c:551
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition idctdsp.c:39
static void idct8_add_ref(uint8_t *dst, const int16_t coeffs[64])
Definition cavsdsp.c:50
#define STRIDE
Definition cavsdsp.c:37
static const int8_t t8[8][8]
Definition cavsdsp.c:39
int main(void)
Definition cavsdsp.c:94
static int check_block(CAVSDSPContext *c, const uint8_t *perm, const int16_t coeffs[64], AVLFG *lfg, int n)
Definition cavsdsp.c:73
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
Definition cpu.c:81
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Context structure for the Lagged Fibonacci PRNG.
Definition lfg.h:33
static uint8_t tmp[40]
Definition aes_ctr.c:52
static int ref[MAX_W *MAX_W]
static double c[64]