FFmpeg
sbrdsp_fixed.c
Go to the documentation of this file.
1 /*
2  * AAC Spectral Band Replication decoding functions
3  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
4  * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * Note: Rounding-to-nearest used unless otherwise stated
23  *
24  */
25 
26 #define USE_FIXED 1
27 
28 #include "aac.h"
29 #include "libavutil/attributes.h"
30 #include "libavutil/intfloat.h"
31 #include "sbrdsp.h"
32 
33 static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
34 {
35  SoftFloat ret;
36  uint64_t accu = 0, round;
37  uint64_t accu0 = 0, accu1 = 0, accu2 = 0, accu3 = 0;
38  int i, nz, nz0;
39  unsigned u;
40 
41  nz = 0;
42  for (i = 0; i < n; i += 2) {
43  accu0 += (int64_t)x[i + 0][0] * x[i + 0][0];
44  accu1 += (int64_t)x[i + 0][1] * x[i + 0][1];
45  accu2 += (int64_t)x[i + 1][0] * x[i + 1][0];
46  accu3 += (int64_t)x[i + 1][1] * x[i + 1][1];
47  if ((accu0|accu1|accu2|accu3) > UINT64_MAX - INT32_MIN*(int64_t)INT32_MIN || i+2>=n) {
48  accu0 >>= nz;
49  accu1 >>= nz;
50  accu2 >>= nz;
51  accu3 >>= nz;
52  while ((accu0|accu1|accu2|accu3) > (UINT64_MAX - accu) >> 2) {
53  accu0 >>= 1;
54  accu1 >>= 1;
55  accu2 >>= 1;
56  accu3 >>= 1;
57  accu >>= 1;
58  nz ++;
59  }
60  accu += accu0 + accu1 + accu2 + accu3;
61  accu0 = accu1 = accu2 = accu3 = 0;
62  }
63  }
64 
65  nz0 = 15 - nz;
66 
67  u = accu >> 32;
68  if (u) {
69  nz = 33;
70  while (u < 0x80000000U) {
71  u <<= 1;
72  nz--;
73  }
74  } else
75  nz = 1;
76 
77  round = 1ULL << (nz-1);
78  u = ((accu + round) >> nz);
79  u >>= 1;
80  ret = av_int2sf(u, nz0 - nz);
81 
82  return ret;
83 }
84 
85 static void sbr_neg_odd_64_c(int *x)
86 {
87  int i;
88  for (i = 1; i < 64; i += 2)
89  x[i] = -(unsigned)x[i];
90 }
91 
92 static void sbr_qmf_pre_shuffle_c(int *z)
93 {
94  int k;
95  z[64] = z[0];
96  z[65] = z[1];
97  for (k = 1; k < 32; k++) {
98  z[64+2*k ] = -z[64 - k];
99  z[64+2*k+1] = z[ k + 1];
100  }
101 }
102 
103 static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
104 {
105  int k;
106  for (k = 0; k < 32; k++) {
107  W[k][0] = -z[63-k];
108  W[k][1] = z[k];
109  }
110 }
111 
112 static void sbr_qmf_deint_neg_c(int *v, const int *src)
113 {
114  int i;
115  for (i = 0; i < 32; i++) {
116  v[ i] = (int)(0x10U + src[63 - 2*i ]) >> 5;
117  v[63 - i] = (int)(0x10U - src[63 - 2*i - 1]) >> 5;
118  }
119 }
120 
122 {
123  int nz, mant, expo;
124  unsigned round;
125  int i = (int)(accu >> 32);
126  if (i == 0) {
127  nz = 1;
128  } else {
129  nz = 0;
130  while (FFABS(i) < 0x40000000) {
131  i *= 2;
132  nz++;
133  }
134  nz = 32-nz;
135  }
136 
137  round = 1U << (nz-1);
138  mant = (int)((accu + round) >> nz);
139  mant = (mant + 0x40LL)>>7;
140  mant *= 64;
141  expo = nz + 15;
142  return av_int2sf(mant, 30 - expo);
143 }
144 
145 static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
146 {
147  int i;
148  int64_t real_sum, imag_sum;
149  int64_t accu_re = 0, accu_im = 0;
150 
151  if (lag) {
152  for (i = 1; i < 38; i++) {
153  accu_re += (uint64_t)x[i][0] * x[i+lag][0];
154  accu_re += (uint64_t)x[i][1] * x[i+lag][1];
155  accu_im += (uint64_t)x[i][0] * x[i+lag][1];
156  accu_im -= (uint64_t)x[i][1] * x[i+lag][0];
157  }
158 
159  real_sum = accu_re;
160  imag_sum = accu_im;
161 
162  accu_re += (uint64_t)x[ 0][0] * x[lag][0];
163  accu_re += (uint64_t)x[ 0][1] * x[lag][1];
164  accu_im += (uint64_t)x[ 0][0] * x[lag][1];
165  accu_im -= (uint64_t)x[ 0][1] * x[lag][0];
166 
167  phi[2-lag][1][0] = autocorr_calc(accu_re);
168  phi[2-lag][1][1] = autocorr_calc(accu_im);
169 
170  if (lag == 1) {
171  accu_re = real_sum;
172  accu_im = imag_sum;
173  accu_re += (uint64_t)x[38][0] * x[39][0];
174  accu_re += (uint64_t)x[38][1] * x[39][1];
175  accu_im += (uint64_t)x[38][0] * x[39][1];
176  accu_im -= (uint64_t)x[38][1] * x[39][0];
177 
178  phi[0][0][0] = autocorr_calc(accu_re);
179  phi[0][0][1] = autocorr_calc(accu_im);
180  }
181  } else {
182  for (i = 1; i < 38; i++) {
183  accu_re += (uint64_t)x[i][0] * x[i][0];
184  accu_re += (uint64_t)x[i][1] * x[i][1];
185  }
186  real_sum = accu_re;
187  accu_re += (uint64_t)x[ 0][0] * x[ 0][0];
188  accu_re += (uint64_t)x[ 0][1] * x[ 0][1];
189 
190  phi[2][1][0] = autocorr_calc(accu_re);
191 
192  accu_re = real_sum;
193  accu_re += (uint64_t)x[38][0] * x[38][0];
194  accu_re += (uint64_t)x[38][1] * x[38][1];
195 
196  phi[1][0][0] = autocorr_calc(accu_re);
197  }
198 }
199 
200 static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
201 {
202  autocorrelate(x, phi, 0);
203  autocorrelate(x, phi, 1);
204  autocorrelate(x, phi, 2);
205 }
206 
207 static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
208  const int alpha0[2], const int alpha1[2],
209  int bw, int start, int end)
210 {
211  int alpha[4];
212  int i;
213  int64_t accu;
214 
215  accu = (int64_t)alpha0[0] * bw;
216  alpha[2] = (int)((accu + 0x40000000) >> 31);
217  accu = (int64_t)alpha0[1] * bw;
218  alpha[3] = (int)((accu + 0x40000000) >> 31);
219  accu = (int64_t)bw * bw;
220  bw = (int)((accu + 0x40000000) >> 31);
221  accu = (int64_t)alpha1[0] * bw;
222  alpha[0] = (int)((accu + 0x40000000) >> 31);
223  accu = (int64_t)alpha1[1] * bw;
224  alpha[1] = (int)((accu + 0x40000000) >> 31);
225 
226  for (i = start; i < end; i++) {
227  accu = (int64_t)X_low[i][0] * 0x20000000;
228  accu += (int64_t)X_low[i - 2][0] * alpha[0];
229  accu -= (int64_t)X_low[i - 2][1] * alpha[1];
230  accu += (int64_t)X_low[i - 1][0] * alpha[2];
231  accu -= (int64_t)X_low[i - 1][1] * alpha[3];
232  X_high[i][0] = (int)((accu + 0x10000000) >> 29);
233 
234  accu = (int64_t)X_low[i][1] * 0x20000000;
235  accu += (int64_t)X_low[i - 2][1] * alpha[0];
236  accu += (int64_t)X_low[i - 2][0] * alpha[1];
237  accu += (int64_t)X_low[i - 1][1] * alpha[2];
238  accu += (int64_t)X_low[i - 1][0] * alpha[3];
239  X_high[i][1] = (int)((accu + 0x10000000) >> 29);
240  }
241 }
242 
243 static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
244  const SoftFloat *g_filt, int m_max, intptr_t ixh)
245 {
246  int m;
247  int64_t accu;
248 
249  for (m = 0; m < m_max; m++) {
250  if (22 - g_filt[m].exp < 61) {
251  int64_t r = 1LL << (22-g_filt[m].exp);
252  accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
253  Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
254 
255  accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
256  Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
257  }
258  }
259 }
260 
261 static av_always_inline int sbr_hf_apply_noise(int (*Y)[2],
262  const SoftFloat *s_m,
263  const SoftFloat *q_filt,
264  int noise,
265  int phi_sign0,
266  int phi_sign1,
267  int m_max)
268 {
269  int m;
270 
271  for (m = 0; m < m_max; m++) {
272  unsigned y0 = Y[m][0];
273  unsigned y1 = Y[m][1];
274  noise = (noise + 1) & 0x1ff;
275  if (s_m[m].mant) {
276  int shift, round;
277 
278  shift = 22 - s_m[m].exp;
279  if (shift < 1) {
280  av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift);
281  return AVERROR(ERANGE);
282  } else if (shift < 30) {
283  round = 1 << (shift-1);
284  y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
285  y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
286  }
287  } else {
288  int shift, round, tmp;
289  int64_t accu;
290 
291  shift = 22 - q_filt[m].exp;
292  if (shift < 1) {
293  av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift);
294  return AVERROR(ERANGE);
295  } else if (shift < 30) {
296  round = 1 << (shift-1);
297 
298  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
299  tmp = (int)((accu + 0x40000000) >> 31);
300  y0 += (tmp + round) >> shift;
301 
302  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
303  tmp = (int)((accu + 0x40000000) >> 31);
304  y1 += (tmp + round) >> shift;
305  }
306  }
307  Y[m][0] = y0;
308  Y[m][1] = y1;
309  phi_sign1 = -phi_sign1;
310  }
311  return 0;
312 }
313 
314 #include "sbrdsp_template.c"
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
sbr_hf_g_filt_c
static void sbr_hf_g_filt_c(int(*Y)[2], const int(*X_high)[40][2], const SoftFloat *g_filt, int m_max, intptr_t ixh)
Definition: sbrdsp_fixed.c:243
int64_t
long long int64_t
Definition: coverity.c:34
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
SoftFloat::mant
int32_t mant
Definition: softfloat.h:35
sbr_hf_gen_c
static void sbr_hf_gen_c(int(*X_high)[2], const int(*X_low)[2], const int alpha0[2], const int alpha1[2], int bw, int start, int end)
Definition: sbrdsp_fixed.c:207
intfloat.h
sbr_autocorrelate_c
static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
Definition: sbrdsp_fixed.c:200
autocorr_calc
static av_always_inline SoftFloat autocorr_calc(int64_t accu)
Definition: sbrdsp_fixed.c:121
noise
static int noise(AVBSFContext *ctx, AVPacket *pkt)
Definition: noise.c:127
autocorrelate
static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
Definition: sbrdsp_fixed.c:145
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
sbr_qmf_post_shuffle_c
static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
Definition: sbrdsp_fixed.c:103
sbr_sum_square_c
static SoftFloat sbr_sum_square_c(int(*x)[2], int n)
Definition: sbrdsp_fixed.c:33
sbr_hf_apply_noise
static av_always_inline int sbr_hf_apply_noise(int(*Y)[2], const SoftFloat *s_m, const SoftFloat *q_filt, int noise, int phi_sign0, int phi_sign1, int m_max)
Definition: sbrdsp_fixed.c:261
W
@ W
Definition: vf_addroi.c:27
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
NULL
#define NULL
Definition: coverity.c:32
sbr_neg_odd_64_c
static void sbr_neg_odd_64_c(int *x)
Definition: sbrdsp_fixed.c:85
aac.h
SoftFloat::exp
int32_t exp
Definition: softfloat.h:36
exp
int8_t exp
Definition: eval.c:73
shift
static int shift(int a, int b)
Definition: bonk.c:261
sbrdsp.h
attributes.h
Y
#define Y
Definition: boxblur.h:37
SoftFloat
Definition: softfloat.h:34
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
round
static av_always_inline av_const double round(double x)
Definition: libm.h:444
av_always_inline
#define av_always_inline
Definition: attributes.h:49
av_int2sf
static av_const SoftFloat av_int2sf(int v, int frac_bits)
Converts a mantisse and exponent to a SoftFloat.
Definition: softfloat.h:185
ret
ret
Definition: filter_design.txt:187
sbr_qmf_pre_shuffle_c
static void sbr_qmf_pre_shuffle_c(int *z)
Definition: sbrdsp_fixed.c:92
U
#define U(x)
Definition: vpx_arith.h:37
sbr_qmf_deint_neg_c
static void sbr_qmf_deint_neg_c(int *v, const int *src)
Definition: sbrdsp_fixed.c:112
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
sbrdsp_template.c
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
src
#define src
Definition: vp8dsp.c:248