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 "config.h"
30 #include "libavutil/attributes.h"
31 #include "libavutil/intfloat.h"
32 #include "sbrdsp.h"
33 
34 static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
35 {
36  SoftFloat ret;
37  uint64_t accu = 0, round;
38  uint64_t accu0 = 0, accu1 = 0, accu2 = 0, accu3 = 0;
39  int i, nz, nz0;
40  unsigned u;
41 
42  nz = 0;
43  for (i = 0; i < n; i += 2) {
44  accu0 += (int64_t)x[i + 0][0] * x[i + 0][0];
45  accu1 += (int64_t)x[i + 0][1] * x[i + 0][1];
46  accu2 += (int64_t)x[i + 1][0] * x[i + 1][0];
47  accu3 += (int64_t)x[i + 1][1] * x[i + 1][1];
48  if ((accu0|accu1|accu2|accu3) > UINT64_MAX - INT32_MIN*(int64_t)INT32_MIN || i+2>=n) {
49  accu0 >>= nz;
50  accu1 >>= nz;
51  accu2 >>= nz;
52  accu3 >>= nz;
53  while ((accu0|accu1|accu2|accu3) > (UINT64_MAX - accu) >> 2) {
54  accu0 >>= 1;
55  accu1 >>= 1;
56  accu2 >>= 1;
57  accu3 >>= 1;
58  accu >>= 1;
59  nz ++;
60  }
61  accu += accu0 + accu1 + accu2 + accu3;
62  accu0 = accu1 = accu2 = accu3 = 0;
63  }
64  }
65 
66  nz0 = 15 - nz;
67 
68  u = accu >> 32;
69  if (u) {
70  nz = 33;
71  while (u < 0x80000000U) {
72  u <<= 1;
73  nz--;
74  }
75  } else
76  nz = 1;
77 
78  round = 1ULL << (nz-1);
79  u = ((accu + round) >> nz);
80  u >>= 1;
81  ret = av_int2sf(u, nz0 - nz);
82 
83  return ret;
84 }
85 
86 static void sbr_neg_odd_64_c(int *x)
87 {
88  int i;
89  for (i = 1; i < 64; i += 2)
90  x[i] = -x[i];
91 }
92 
93 static void sbr_qmf_pre_shuffle_c(int *z)
94 {
95  int k;
96  z[64] = z[0];
97  z[65] = z[1];
98  for (k = 1; k < 32; k++) {
99  z[64+2*k ] = -z[64 - k];
100  z[64+2*k+1] = z[ k + 1];
101  }
102 }
103 
104 static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
105 {
106  int k;
107  for (k = 0; k < 32; k++) {
108  W[k][0] = -z[63-k];
109  W[k][1] = z[k];
110  }
111 }
112 
113 static void sbr_qmf_deint_neg_c(int *v, const int *src)
114 {
115  int i;
116  for (i = 0; i < 32; i++) {
117  v[ i] = ( src[63 - 2*i ] + 0x10) >> 5;
118  v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
119  }
120 }
121 
123 {
124  int nz, mant, expo;
125  unsigned round;
126  int i = (int)(accu >> 32);
127  if (i == 0) {
128  nz = 1;
129  } else {
130  nz = 0;
131  while (FFABS(i) < 0x40000000) {
132  i *= 2;
133  nz++;
134  }
135  nz = 32-nz;
136  }
137 
138  round = 1U << (nz-1);
139  mant = (int)((accu + round) >> nz);
140  mant = (mant + 0x40LL)>>7;
141  mant *= 64;
142  expo = nz + 15;
143  return av_int2sf(mant, 30 - expo);
144 }
145 
146 static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
147 {
148  int i;
149  int64_t real_sum, imag_sum;
150  int64_t accu_re = 0, accu_im = 0;
151 
152  if (lag) {
153  for (i = 1; i < 38; i++) {
154  accu_re += (uint64_t)x[i][0] * x[i+lag][0];
155  accu_re += (uint64_t)x[i][1] * x[i+lag][1];
156  accu_im += (uint64_t)x[i][0] * x[i+lag][1];
157  accu_im -= (uint64_t)x[i][1] * x[i+lag][0];
158  }
159 
160  real_sum = accu_re;
161  imag_sum = accu_im;
162 
163  accu_re += (uint64_t)x[ 0][0] * x[lag][0];
164  accu_re += (uint64_t)x[ 0][1] * x[lag][1];
165  accu_im += (uint64_t)x[ 0][0] * x[lag][1];
166  accu_im -= (uint64_t)x[ 0][1] * x[lag][0];
167 
168  phi[2-lag][1][0] = autocorr_calc(accu_re);
169  phi[2-lag][1][1] = autocorr_calc(accu_im);
170 
171  if (lag == 1) {
172  accu_re = real_sum;
173  accu_im = imag_sum;
174  accu_re += (uint64_t)x[38][0] * x[39][0];
175  accu_re += (uint64_t)x[38][1] * x[39][1];
176  accu_im += (uint64_t)x[38][0] * x[39][1];
177  accu_im -= (uint64_t)x[38][1] * x[39][0];
178 
179  phi[0][0][0] = autocorr_calc(accu_re);
180  phi[0][0][1] = autocorr_calc(accu_im);
181  }
182  } else {
183  for (i = 1; i < 38; i++) {
184  accu_re += (uint64_t)x[i][0] * x[i][0];
185  accu_re += (uint64_t)x[i][1] * x[i][1];
186  }
187  real_sum = accu_re;
188  accu_re += (uint64_t)x[ 0][0] * x[ 0][0];
189  accu_re += (uint64_t)x[ 0][1] * x[ 0][1];
190 
191  phi[2][1][0] = autocorr_calc(accu_re);
192 
193  accu_re = real_sum;
194  accu_re += (uint64_t)x[38][0] * x[38][0];
195  accu_re += (uint64_t)x[38][1] * x[38][1];
196 
197  phi[1][0][0] = autocorr_calc(accu_re);
198  }
199 }
200 
201 static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
202 {
203  autocorrelate(x, phi, 0);
204  autocorrelate(x, phi, 1);
205  autocorrelate(x, phi, 2);
206 }
207 
208 static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
209  const int alpha0[2], const int alpha1[2],
210  int bw, int start, int end)
211 {
212  int alpha[4];
213  int i;
214  int64_t accu;
215 
216  accu = (int64_t)alpha0[0] * bw;
217  alpha[2] = (int)((accu + 0x40000000) >> 31);
218  accu = (int64_t)alpha0[1] * bw;
219  alpha[3] = (int)((accu + 0x40000000) >> 31);
220  accu = (int64_t)bw * bw;
221  bw = (int)((accu + 0x40000000) >> 31);
222  accu = (int64_t)alpha1[0] * bw;
223  alpha[0] = (int)((accu + 0x40000000) >> 31);
224  accu = (int64_t)alpha1[1] * bw;
225  alpha[1] = (int)((accu + 0x40000000) >> 31);
226 
227  for (i = start; i < end; i++) {
228  accu = (int64_t)X_low[i][0] * 0x20000000;
229  accu += (int64_t)X_low[i - 2][0] * alpha[0];
230  accu -= (int64_t)X_low[i - 2][1] * alpha[1];
231  accu += (int64_t)X_low[i - 1][0] * alpha[2];
232  accu -= (int64_t)X_low[i - 1][1] * alpha[3];
233  X_high[i][0] = (int)((accu + 0x10000000) >> 29);
234 
235  accu = (int64_t)X_low[i][1] * 0x20000000;
236  accu += (int64_t)X_low[i - 2][1] * alpha[0];
237  accu += (int64_t)X_low[i - 2][0] * alpha[1];
238  accu += (int64_t)X_low[i - 1][1] * alpha[2];
239  accu += (int64_t)X_low[i - 1][0] * alpha[3];
240  X_high[i][1] = (int)((accu + 0x10000000) >> 29);
241  }
242 }
243 
244 static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
245  const SoftFloat *g_filt, int m_max, intptr_t ixh)
246 {
247  int m;
248  int64_t accu;
249 
250  for (m = 0; m < m_max; m++) {
251  if (22 - g_filt[m].exp < 61) {
252  int64_t r = 1LL << (22-g_filt[m].exp);
253  accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
254  Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
255 
256  accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
257  Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
258  }
259  }
260 }
261 
262 static av_always_inline int sbr_hf_apply_noise(int (*Y)[2],
263  const SoftFloat *s_m,
264  const SoftFloat *q_filt,
265  int noise,
266  int phi_sign0,
267  int phi_sign1,
268  int m_max)
269 {
270  int m;
271 
272  for (m = 0; m < m_max; m++) {
273  unsigned y0 = Y[m][0];
274  unsigned y1 = Y[m][1];
275  noise = (noise + 1) & 0x1ff;
276  if (s_m[m].mant) {
277  int shift, round;
278 
279  shift = 22 - s_m[m].exp;
280  if (shift < 1) {
281  av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift);
282  return AVERROR(ERANGE);
283  } else if (shift < 30) {
284  round = 1 << (shift-1);
285  y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
286  y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
287  }
288  } else {
289  int shift, round, tmp;
290  int64_t accu;
291 
292  shift = 22 - q_filt[m].exp;
293  if (shift < 1) {
294  av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift);
295  return AVERROR(ERANGE);
296  } else if (shift < 30) {
297  round = 1 << (shift-1);
298 
299  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
300  tmp = (int)((accu + 0x40000000) >> 31);
301  y0 += (tmp + round) >> shift;
302 
303  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
304  tmp = (int)((accu + 0x40000000) >> 31);
305  y1 += (tmp + round) >> shift;
306  }
307  }
308  Y[m][0] = y0;
309  Y[m][1] = y1;
310  phi_sign1 = -phi_sign1;
311  }
312  return 0;
313 }
314 
315 #include "sbrdsp_template.c"
#define NULL
Definition: coverity.c:32
static int shift(int a, int b)
Definition: sonic.c:82
static av_always_inline SoftFloat autocorr_calc(int64_t accu)
Definition: sbrdsp_fixed.c:122
static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
Definition: sbrdsp_fixed.c:201
#define src
Definition: vp8dsp.c:254
Definition: vf_addroi.c:26
Macro definitions for various function/variable attributes.
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:244
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
int32_t mant
Definition: softfloat.h:35
#define av_log(a,...)
static SoftFloat sbr_sum_square_c(int(*x)[2], int n)
Definition: sbrdsp_fixed.c:34
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
Definition: sbrdsp_fixed.c:146
const char * r
Definition: vf_curves.c:114
static av_always_inline av_const double round(double x)
Definition: libm.h:444
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:262
int8_t exp
Definition: eval.c:72
static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
Definition: sbrdsp_fixed.c:104
#define Y
Definition: boxblur.h:38
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
AAC definitions and structures.
int n
Definition: avisynth_c.h:760
static void sbr_neg_odd_64_c(int *x)
Definition: sbrdsp_fixed.c:86
static const int16_t alpha[]
Definition: ilbcdata.h:55
static void sbr_qmf_pre_shuffle_c(int *z)
Definition: sbrdsp_fixed.c:93
static int noise(AVBSFContext *ctx, AVPacket *pkt)
Definition: noise_bsf.c:38
int
int32_t exp
Definition: softfloat.h:36
static void sbr_qmf_deint_neg_c(int *v, const int *src)
Definition: sbrdsp_fixed.c:113
static av_const SoftFloat av_int2sf(int v, int frac_bits)
Converts a mantisse and exponent to a SoftFloat.
Definition: softfloat.h:185
void INT64 start
Definition: avisynth_c.h:766
#define av_always_inline
Definition: attributes.h:39
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
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:208
static uint8_t tmp[11]
Definition: aes_ctr.c:26