FFmpeg
alacdsp.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/alacdsp.h"
24 #include "libavcodec/mathops.h"
25 #include "libavutil/common.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/mem_internal.h"
28 
29 #define BUF_SIZE 256
30 #define MAX_CHANNELS 2
31 
32 #define randomize_buffers() \
33  do { \
34  int i; \
35  for (i = 0; i < BUF_SIZE*MAX_CHANNELS; i++) { \
36  int32_t r = sign_extend(rnd(), 24); \
37  ref_buf[i] = r; \
38  new_buf[i] = r; \
39  } \
40  } while (0)
41 
42 static void check_decorrelate_stereo(void)
43 {
45  LOCAL_ALIGNED_16(int32_t, new_buf, [BUF_SIZE*MAX_CHANNELS]);
46  int32_t *ref[2] = { &ref_buf[BUF_SIZE*0], &ref_buf[BUF_SIZE*1] };
47  int32_t *new[2] = { &new_buf[BUF_SIZE*0], &new_buf[BUF_SIZE*1] };
49 
50  ff_alacdsp_init(&c);
51  if (check_func(c.decorrelate_stereo, "alac_decorrelate_stereo")) {
52  int len = (rnd() & 0xFF) + 1;
53  int shift = rnd() & 0x1F;
54  int weight = rnd() & 0xFF;
55  declare_func(void, int32_t *buf[2], int len, int shift, int weight);
56 
58  call_ref(ref, len, shift, weight);
59  call_new(new, len, shift, weight);
60  if (memcmp(ref[0], new[0], len * sizeof(int32_t)) ||
61  memcmp(ref[1], new[1], len * sizeof(int32_t)))
62  fail();
63  bench_new(new, BUF_SIZE, shift, weight);
64  }
65 
66  report("decorrelate_stereo");
67 }
68 
69 #undef randomize_buffers
70 #define randomize_buffers() \
71  do { \
72  int i, j; \
73  for (i = 0; i < BUF_SIZE; i++) { \
74  for (j = 0; j < ch; j++) { \
75  int32_t r = sign_extend(rnd(), 24); \
76  ref[j][i] = r; \
77  new[j][i] = r; \
78  r = rnd() & 0xFF; \
79  ref_ebb[j][i] = r; \
80  new_ebb[j][i] = r; \
81  } \
82  } \
83  } while (0)
84 
85 static void check_append_extra_bits(void)
86 {
88  LOCAL_ALIGNED_16(int32_t, new_buf, [BUF_SIZE*MAX_CHANNELS*2]);
89  int32_t *ref[2] = { &ref_buf[BUF_SIZE*0], &ref_buf[BUF_SIZE*1] };
90  int32_t *new[2] = { &new_buf[BUF_SIZE*0], &new_buf[BUF_SIZE*1] };
91  int32_t *ref_ebb[2] = { &ref_buf[BUF_SIZE*2], &ref_buf[BUF_SIZE*3] };
92  int32_t *new_ebb[2] = { &new_buf[BUF_SIZE*2], &new_buf[BUF_SIZE*3] };
94  static const char * const channels[2] = { "mono", "stereo" };
95  int ch;
96 
97  ff_alacdsp_init(&c);
98  for (ch = 1; ch <= 2; ch++) {
99  if (check_func(c.append_extra_bits[ch-1], "alac_append_extra_bits_%s", channels[ch-1])) {
100  int len = (rnd() & 0xFF) + 1;
101  declare_func(void, int32_t *buf[2], int32_t *ebb[2], int ebits, int ch, int len);
102 
104  call_ref(ref, ref_ebb, 8, ch, len);
105  call_new(new, new_ebb, 8, ch, len);
106  if ( memcmp(ref[0], new[0], len * sizeof(int32_t)) ||
107  (ch == 2 && memcmp(ref[1], new[1], len * sizeof(int32_t))))
108  fail();
109  bench_new(new, new_ebb, 8, ch, BUF_SIZE);
110  }
111  }
112 
113  report("append_extra_bits");
114 }
115 
117 {
120 }
static int shift(int a, int b)
Definition: sonic.c:82
#define BUF_SIZE
Definition: alacdsp.c:29
#define MAX_CHANNELS
Definition: alacdsp.c:30
void checkasm_check_alacdsp(void)
Definition: alacdsp.c:116
#define report
Definition: checkasm.h:136
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
channels
Definition: aptx.h:33
#define declare_func(ret,...)
Definition: checkasm.h:128
static void check_decorrelate_stereo(void)
Definition: alacdsp.c:42
#define fail()
Definition: checkasm.h:133
common internal API header
static void check_append_extra_bits(void)
Definition: alacdsp.c:85
#define randomize_buffers()
Definition: alacdsp.c:70
int32_t
#define call_ref(...)
Definition: checkasm.h:139
#define check_func(func,...)
Definition: checkasm.h:124
void(* append_extra_bits[2])(int32_t *buffer[2], int32_t *extra_bits_buffer[2], int extra_bits, int channels, int nb_samples)
Definition: alacdsp.h:27
static int weight(int i, int blen, int offset)
Definition: diracdec.c:1561
void(* decorrelate_stereo)(int32_t *buffer[2], int nb_samples, int decorr_shift, int decorr_left_weight)
Definition: alacdsp.h:25
common internal and external API header
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
#define rnd()
Definition: checkasm.h:117
int len
#define bench_new(...)
Definition: checkasm.h:271
#define call_new(...)
Definition: checkasm.h:211
av_cold void ff_alacdsp_init(ALACDSPContext *c)
Definition: alacdsp.c:55