FFmpeg
Loading...
Searching...
No Matches
flacdsp.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 James Almer
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <string.h>
22#include "checkasm.h"
23#include "libavcodec/flacdsp.h"
24#include "libavcodec/mathops.h"
25#include "libavutil/common.h"
26#include "libavutil/internal.h"
29
30#define BUF_SIZE 256
31#define MAX_CHANNELS 8
32
33#define randomize_buffers() \
34 do { \
35 int i, j; \
36 for (i = 0; i < BUF_SIZE; i += 4) { \
37 for (j = 0; j < channels; j++) { \
38 uint32_t r = rnd() & (1 << (bits - 2)) - 1; \
39 AV_WN32A(ref_src[j] + i, r); \
40 AV_WN32A(new_src[j] + i, r); \
41 } \
42 } \
43 } while (0)
44
45static void check_decorrelate(uint8_t **ref_dst, uint8_t **ref_src, uint8_t **new_dst, uint8_t **new_src,
46 int channels, int bits) {
47 declare_func(void, uint8_t **out, int32_t **in, int channels, int len, int shift);
48
50 call_ref(ref_dst, (int32_t **)ref_src, channels, BUF_SIZE / sizeof(int32_t), 8);
51 call_new(new_dst, (int32_t **)new_src, channels, BUF_SIZE / sizeof(int32_t), 8);
52 if (memcmp(*ref_dst, *new_dst, bits == 16 ? BUF_SIZE * (channels/2) : BUF_SIZE * channels) ||
53 memcmp(*ref_src, *new_src, BUF_SIZE * channels))
54 fail();
55 bench_new(new_dst, (int32_t **)new_src, channels, BUF_SIZE / sizeof(int32_t), 8);
56}
57
58static void check_lpc(int pred_order, int bps)
59{
60 int qlevel = rnd() % 16;
61 int coeff_prec = (rnd() % 15) + 1;
62 LOCAL_ALIGNED_16(int32_t, coeffs, [32]);
66
67 declare_func(void, int32_t *, const int[32], int, int, int);
68
69 if (bps <= 16)
70 coeff_prec = av_clip(coeff_prec, 0, 32 - bps - av_log2(pred_order));
71
72 for (int i = 0; i < 32; i++)
73 coeffs[i] = sign_extend(rnd(), coeff_prec);
74 for (int i = 0; i < BUF_SIZE; i++)
75 dst[i] = sign_extend(rnd(), bps);
76
77 const int test_lens[] = {
78 0,
79 pred_order - 1,
80 pred_order,
81 pred_order + 1,
83 };
84
85 for (int k = 0; k < FF_ARRAY_ELEMS(test_lens); k++) {
86 int len = test_lens[k];
87 if (len < 0 || len > BUF_SIZE) continue;
88
89 memcpy(dst0, dst, BUF_SIZE * sizeof (int32_t));
90 memcpy(dst1, dst, BUF_SIZE * sizeof (int32_t));
91 call_ref(dst0, coeffs, pred_order, qlevel, len);
92 call_new(dst1, coeffs, pred_order, qlevel, len);
93 if (memcmp(dst0, dst1, BUF_SIZE * sizeof (int32_t)) != 0)
94 fail();
95 }
96 bench_new(dst, coeffs, pred_order, qlevel, BUF_SIZE);
97}
98
99static void check_lpc33(int pred_order)
100{
101 int qlevel = rnd() % 16;
102 int coeff_prec = (rnd() % 15) + 1;
106 LOCAL_ALIGNED_16(int32_t, residuals, [BUF_SIZE]);
107 LOCAL_ALIGNED_16(int32_t, coeffs, [32]);
108
109 declare_func(void, int64_t *, const int32_t *, const int[32], int, int, int);
110
111 for (int i = 0; i < 32; i++)
112 coeffs[i] = sign_extend(rnd(), coeff_prec);
113
114 for (int i = 0; i < BUF_SIZE; i++) {
115 residuals[i] = sign_extend(rnd(), pred_order);
116 dst[i] = sign_extend64(((int64_t)rnd() << 1) | (rnd() & 1), 33);
117 }
118
119 const int test_lens[] = {
120 0,
121 pred_order - 1,
122 pred_order,
123 pred_order + 1,
124 BUF_SIZE,
125 };
126
127 for (int k = 0; k < FF_ARRAY_ELEMS(test_lens); k++) {
128 int len = test_lens[k];
129 if (len < 0 || len > BUF_SIZE) continue;
130
131 memcpy(dst0, dst, BUF_SIZE * sizeof (int64_t));
132 memcpy(dst1, dst, BUF_SIZE * sizeof (int64_t));
133 call_ref(dst0, residuals, coeffs, pred_order, qlevel, len);
134 call_new(dst1, residuals, coeffs, pred_order, qlevel, len);
135 if (memcmp(dst0, dst1, BUF_SIZE * sizeof (int64_t)) != 0)
136 fail();
137 }
138 bench_new(dst, residuals, coeffs, pred_order, qlevel, BUF_SIZE);
139}
140
141static void check_wasted32(void)
142{
143 int wasted = rnd() % 32;
147
148 declare_func(void, int32_t *, int, int);
149
150 for (int i = 0; i < BUF_SIZE; i++)
151 dst[i] = rnd();
152
153 memcpy(dst0, dst, BUF_SIZE * sizeof (int32_t));
154 memcpy(dst1, dst, BUF_SIZE * sizeof (int32_t));
155 call_ref(dst0, wasted, BUF_SIZE);
156 call_new(dst1, wasted, BUF_SIZE);
157 if (memcmp(dst0, dst1, BUF_SIZE * sizeof (int32_t)) != 0)
158 fail();
159 bench_new(dst, wasted, BUF_SIZE);
160}
161
162static void check_wasted33(void)
163{
164 int wasted = rnd() % 33;
167 LOCAL_ALIGNED_16(int32_t, residuals, [BUF_SIZE]);
168
169 declare_func(void, int64_t *, const int32_t *, int, int);
170
171 for (int i = 0; i < BUF_SIZE; i++)
172 residuals[i] = rnd();
173
174 call_ref(dst0, residuals, wasted, BUF_SIZE);
175 call_new(dst1, residuals, wasted, BUF_SIZE);
176 if (memcmp(dst0, dst1, BUF_SIZE * sizeof (int64_t)) != 0)
177 fail();
178 bench_new(dst0, residuals, wasted, BUF_SIZE);
179}
180
182{
183 LOCAL_ALIGNED_16(uint8_t, ref_dst, [BUF_SIZE*MAX_CHANNELS]);
184 LOCAL_ALIGNED_16(uint8_t, ref_buf, [BUF_SIZE*MAX_CHANNELS]);
185 LOCAL_ALIGNED_16(uint8_t, new_dst, [BUF_SIZE*MAX_CHANNELS]);
186 LOCAL_ALIGNED_16(uint8_t, new_buf, [BUF_SIZE*MAX_CHANNELS]);
187 uint8_t *ref_src[] = { &ref_buf[BUF_SIZE*0], &ref_buf[BUF_SIZE*1], &ref_buf[BUF_SIZE*2], &ref_buf[BUF_SIZE*3],
188 &ref_buf[BUF_SIZE*4], &ref_buf[BUF_SIZE*5], &ref_buf[BUF_SIZE*6], &ref_buf[BUF_SIZE*7] };
189 uint8_t *new_src[] = { &new_buf[BUF_SIZE*0], &new_buf[BUF_SIZE*1], &new_buf[BUF_SIZE*2], &new_buf[BUF_SIZE*3],
190 &new_buf[BUF_SIZE*4], &new_buf[BUF_SIZE*5], &new_buf[BUF_SIZE*6], &new_buf[BUF_SIZE*7] };
191 static const char * const names[3] = { "ls", "rs", "ms" };
192 static const struct {
193 enum AVSampleFormat fmt;
194 int bits;
195 } fmts[] = {
196 { AV_SAMPLE_FMT_S16, 16 },
197 { AV_SAMPLE_FMT_S32, 32 },
198 };
199 static const signed char pred_orders[] = { 13, 16, 29, 32 };
201 int i, j;
202
203 for (i = 0; i < 2; i++) {
204 ff_flacdsp_init(&h, fmts[i].fmt, 2);
205 for (j = 0; j < 3; j++)
206 if (check_func(h.decorrelate[j + 1], "flac_decorrelate_%s_%d", names[j], fmts[i].bits))
207 check_decorrelate(&ref_dst, ref_src, &new_dst, new_src, 2, fmts[i].bits);
208 for (j = 2; j <= MAX_CHANNELS; j += 2) {
209 ff_flacdsp_init(&h, fmts[i].fmt, j);
210 if (check_func(h.decorrelate[0], "flac_decorrelate_indep%d_%d", j, fmts[i].bits))
211 check_decorrelate(&ref_dst, ref_src, &new_dst, new_src, j, fmts[i].bits);
212 }
213 }
214
215 report("decorrelate");
216
217 for (i = 0; i < FF_ARRAY_ELEMS(pred_orders); i++)
218 if (check_func(h.lpc16, "flac_lpc_16_%d", pred_orders[i]))
219 check_lpc(pred_orders[i], 16);
220 for (i = 0; i < FF_ARRAY_ELEMS(pred_orders); i++)
221 if (check_func(h.lpc32, "flac_lpc_32_%d", pred_orders[i]))
222 check_lpc(pred_orders[i], 32);
223 for (i = 0; i < FF_ARRAY_ELEMS(pred_orders); i++)
224 if (check_func(h.lpc33, "flac_lpc_33_%d", pred_orders[i]))
225 check_lpc33(pred_orders[i]);
226
227 report("lpc");
228
229 if (check_func(h.wasted32, "flac_wasted_32"))
231 if (check_func(h.wasted33, "flac_wasted_33"))
233
234 report("wasted");
235}
#define MAX_CHANNELS
Definition aac.h:33
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
channels
Definition aptx.h:31
int32_t
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define rnd
Definition checkasm.h:136
common internal and external API header
#define av_clip
Definition common.h:100
long long int64_t
Definition coverity.c:34
static const uint8_t bits[8]
Definition fastaudio.c:100
#define declare_func
Definition test.h:489
#define fail
Definition test.h:479
#define bench_new
Definition test.h:487
#define check_func
Definition test.h:481
#define call_new
Definition test.h:486
#define call_ref
Definition test.h:485
#define report
Definition test.h:480
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition samplefmt.h:59
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
#define av_log2
Definition intmath.h:84
static int shift(int a, int b)
Definition bonk.c:261
av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels)
Definition flacdsp.c:114
common internal API header
static av_const int sign_extend(int val, unsigned bits)
Definition mathops.h:135
static av_const int64_t sign_extend64(int64_t val, unsigned bits)
Definition mathops.h:144
#define LOCAL_ALIGNED_16(t, v,...)
unsigned bps
Definition movenc.c:2074
#define BUF_SIZE
Definition setpts.c:159
#define FF_ARRAY_ELEMS(a)
#define randomize_buffers()
Definition flacdsp.c:33
void checkasm_check_flacdsp(void)
Definition flacdsp.c:181
static void check_lpc(int pred_order, int bps)
Definition flacdsp.c:58
static void check_lpc33(int pred_order)
Definition flacdsp.c:99
static void check_decorrelate(uint8_t **ref_dst, uint8_t **ref_src, uint8_t **new_dst, uint8_t **new_src, int channels, int bits)
Definition flacdsp.c:45
static void check_wasted33(void)
Definition flacdsp.c:162
static void check_wasted32(void)
Definition flacdsp.c:141
static FILE * out
Definition movenc.c:55
int len