FFmpeg
aacpsdsp_template.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * Note: Rounding-to-nearest used unless otherwise stated
21  *
22  */
23 #include <stdint.h>
24 
25 #include "config.h"
26 #include "libavutil/attributes.h"
27 #include "aacpsdsp.h"
28 
29 static void ps_add_squares_c(INTFLOAT *dst, const INTFLOAT (*src)[2], int n)
30 {
31  int i;
32  for (i = 0; i < n; i++)
33  dst[i] += (UINTFLOAT)AAC_MADD28(src[i][0], src[i][0], src[i][1], src[i][1]);
34 }
35 
36 static void ps_mul_pair_single_c(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1,
37  int n)
38 {
39  int i;
40  for (i = 0; i < n; i++) {
41  dst[i][0] = AAC_MUL16(src0[i][0], src1[i]);
42  dst[i][1] = AAC_MUL16(src0[i][1], src1[i]);
43  }
44 }
45 
46 static void ps_hybrid_analysis_c(INTFLOAT (*out)[2], INTFLOAT (*in)[2],
47  const INTFLOAT (*filter)[8][2],
48  ptrdiff_t stride, int n)
49 {
50  INT64FLOAT inre0[6], inre1[6], inim0[6], inim1[6];
51 
52  for (int j = 0; j < 6; j++) {
53  inre0[j] = in[j][0] + in[12 - j][0];
54  inre1[j] = in[j][1] - in[12 - j][1];
55  inim0[j] = in[j][1] + in[12 - j][1];
56  inim1[j] = in[j][0] - in[12 - j][0];
57  }
58 
59  for (int i = 0; i < n; i++) {
60  INT64FLOAT sum_re = (INT64FLOAT)filter[i][6][0] * in[6][0];
61  INT64FLOAT sum_im = (INT64FLOAT)filter[i][6][0] * in[6][1];
62 
63  for (int j = 0; j < 6; j++) {
64  sum_re += (INT64FLOAT)filter[i][j][0] * inre0[j] -
65  (INT64FLOAT)filter[i][j][1] * inre1[j];
66  sum_im += (INT64FLOAT)filter[i][j][0] * inim0[j] +
67  (INT64FLOAT)filter[i][j][1] * inim1[j];
68  }
69 #if USE_FIXED
70  out[i * stride][0] = (int)((sum_re + 0x40000000) >> 31);
71  out[i * stride][1] = (int)((sum_im + 0x40000000) >> 31);
72 #else
73  out[i * stride][0] = sum_re;
74  out[i * stride][1] = sum_im;
75 #endif /* USE_FIXED */
76  }
77 }
78 
79 static void ps_hybrid_analysis_ileave_c(INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64],
80  int i, int len)
81 {
82  int j;
83 
84  for (; i < 64; i++) {
85  for (j = 0; j < len; j++) {
86  out[i][j][0] = L[0][j][i];
87  out[i][j][1] = L[1][j][i];
88  }
89  }
90 }
91 
92 static void ps_hybrid_synthesis_deint_c(INTFLOAT out[2][38][64],
93  INTFLOAT (*in)[32][2],
94  int i, int len)
95 {
96  int n;
97 
98  for (; i < 64; i++) {
99  for (n = 0; n < len; n++) {
100  out[0][n][i] = in[i][n][0];
101  out[1][n][i] = in[i][n][1];
102  }
103  }
104 }
105 
106 static void ps_decorrelate_c(INTFLOAT (*out)[2], INTFLOAT (*delay)[2],
107  INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
108  const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2],
109  const INTFLOAT *transient_gain,
110  INTFLOAT g_decay_slope,
111  int len)
112 {
113  static const INTFLOAT a[] = { Q31(0.65143905753106f),
114  Q31(0.56471812200776f),
115  Q31(0.48954165955695f) };
116  INTFLOAT ag[PS_AP_LINKS];
117  int m, n;
118 
119  for (m = 0; m < PS_AP_LINKS; m++)
120  ag[m] = AAC_MUL30(a[m], g_decay_slope);
121 
122  for (n = 0; n < len; n++) {
123  INTFLOAT in_re = AAC_MSUB30(delay[n][0], phi_fract[0], delay[n][1], phi_fract[1]);
124  INTFLOAT in_im = AAC_MADD30(delay[n][0], phi_fract[1], delay[n][1], phi_fract[0]);
125  for (m = 0; m < PS_AP_LINKS; m++) {
126  INTFLOAT a_re = AAC_MUL31(ag[m], in_re);
127  INTFLOAT a_im = AAC_MUL31(ag[m], in_im);
128  INTFLOAT link_delay_re = ap_delay[m][n+2-m][0];
129  INTFLOAT link_delay_im = ap_delay[m][n+2-m][1];
130  INTFLOAT fractional_delay_re = Q_fract[m][0];
131  INTFLOAT fractional_delay_im = Q_fract[m][1];
132  INTFLOAT apd_re = in_re;
133  INTFLOAT apd_im = in_im;
134  in_re = AAC_MSUB30(link_delay_re, fractional_delay_re,
135  link_delay_im, fractional_delay_im);
136  in_re -= (UINTFLOAT)a_re;
137  in_im = AAC_MADD30(link_delay_re, fractional_delay_im,
138  link_delay_im, fractional_delay_re);
139  in_im -= (UINTFLOAT)a_im;
140  ap_delay[m][n+5][0] = apd_re + (UINTFLOAT)AAC_MUL31(ag[m], in_re);
141  ap_delay[m][n+5][1] = apd_im + (UINTFLOAT)AAC_MUL31(ag[m], in_im);
142  }
143  out[n][0] = AAC_MUL16(transient_gain[n], in_re);
144  out[n][1] = AAC_MUL16(transient_gain[n], in_im);
145  }
146 }
147 
148 static void ps_stereo_interpolate_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2],
149  INTFLOAT h[2][4], INTFLOAT h_step[2][4],
150  int len)
151 {
152  INTFLOAT h0 = h[0][0];
153  INTFLOAT h1 = h[0][1];
154  INTFLOAT h2 = h[0][2];
155  INTFLOAT h3 = h[0][3];
156  UINTFLOAT hs0 = h_step[0][0];
157  UINTFLOAT hs1 = h_step[0][1];
158  UINTFLOAT hs2 = h_step[0][2];
159  UINTFLOAT hs3 = h_step[0][3];
160  int n;
161 
162  for (n = 0; n < len; n++) {
163  //l is s, r is d
164  INTFLOAT l_re = l[n][0];
165  INTFLOAT l_im = l[n][1];
166  INTFLOAT r_re = r[n][0];
167  INTFLOAT r_im = r[n][1];
168  h0 += hs0;
169  h1 += hs1;
170  h2 += hs2;
171  h3 += hs3;
172  l[n][0] = AAC_MADD30(h0, l_re, h2, r_re);
173  l[n][1] = AAC_MADD30(h0, l_im, h2, r_im);
174  r[n][0] = AAC_MADD30(h1, l_re, h3, r_re);
175  r[n][1] = AAC_MADD30(h1, l_im, h3, r_im);
176  }
177 }
178 
180  INTFLOAT h[2][4], INTFLOAT h_step[2][4],
181  int len)
182 {
183  INTFLOAT h00 = h[0][0], h10 = h[1][0];
184  INTFLOAT h01 = h[0][1], h11 = h[1][1];
185  INTFLOAT h02 = h[0][2], h12 = h[1][2];
186  INTFLOAT h03 = h[0][3], h13 = h[1][3];
187  UINTFLOAT hs00 = h_step[0][0], hs10 = h_step[1][0];
188  UINTFLOAT hs01 = h_step[0][1], hs11 = h_step[1][1];
189  UINTFLOAT hs02 = h_step[0][2], hs12 = h_step[1][2];
190  UINTFLOAT hs03 = h_step[0][3], hs13 = h_step[1][3];
191  int n;
192 
193  for (n = 0; n < len; n++) {
194  //l is s, r is d
195  INTFLOAT l_re = l[n][0];
196  INTFLOAT l_im = l[n][1];
197  INTFLOAT r_re = r[n][0];
198  INTFLOAT r_im = r[n][1];
199  h00 += hs00;
200  h01 += hs01;
201  h02 += hs02;
202  h03 += hs03;
203  h10 += hs10;
204  h11 += hs11;
205  h12 += hs12;
206  h13 += hs13;
207 
208  l[n][0] = AAC_MSUB30_V8(h00, l_re, h02, r_re, h10, l_im, h12, r_im);
209  l[n][1] = AAC_MADD30_V8(h00, l_im, h02, r_im, h10, l_re, h12, r_re);
210  r[n][0] = AAC_MSUB30_V8(h01, l_re, h03, r_re, h11, l_im, h13, r_im);
211  r[n][1] = AAC_MADD30_V8(h01, l_im, h03, r_im, h11, l_re, h13, r_re);
212  }
213 }
214 
216 {
217  s->add_squares = ps_add_squares_c;
218  s->mul_pair_single = ps_mul_pair_single_c;
219  s->hybrid_analysis = ps_hybrid_analysis_c;
220  s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c;
221  s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c;
222  s->decorrelate = ps_decorrelate_c;
223  s->stereo_interpolate[0] = ps_stereo_interpolate_c;
224  s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c;
225 
226 #if !USE_FIXED
227 #if ARCH_ARM
229 #elif ARCH_AARCH64
231 #elif ARCH_MIPS
233 #elif ARCH_RISCV
235 #elif ARCH_X86
237 #endif
238 #endif /* !USE_FIXED */
239 }
AAC_MADD30
#define AAC_MADD30(x, y, a, b)
Definition: aac_defines.h:100
h0
static const float h0[64]
Definition: speexdata.h:741
r
const char * r
Definition: vf_curves.c:126
out
FILE * out
Definition: movenc.c:54
src1
const pixel * src1
Definition: h264pred_template.c:421
ff_psdsp_init_x86
void ff_psdsp_init_x86(PSDSPContext *s)
Definition: aacpsdsp_init.c:52
PS_QMF_TIME_SLOTS
#define PS_QMF_TIME_SLOTS
Definition: aacps.h:38
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
ff_psdsp_init_mips
void ff_psdsp_init_mips(PSDSPContext *s)
Definition: aacpsdsp_mips.c:451
ps_stereo_interpolate_c
static void ps_stereo_interpolate_c(INTFLOAT(*l)[2], INTFLOAT(*r)[2], INTFLOAT h[2][4], INTFLOAT h_step[2][4], int len)
Definition: aacpsdsp_template.c:148
ff_psdsp_init_arm
void ff_psdsp_init_arm(PSDSPContext *s)
Definition: aacpsdsp_init_arm.c:46
ps_hybrid_analysis_ileave_c
static void ps_hybrid_analysis_ileave_c(INTFLOAT(*out)[32][2], INTFLOAT L[2][38][64], int i, int len)
Definition: aacpsdsp_template.c:79
av_cold
#define av_cold
Definition: attributes.h:90
aacpsdsp.h
AAC_MUL31
#define AAC_MUL31(x, y)
Definition: aac_defines.h:98
ff_psdsp_init_aarch64
void ff_psdsp_init_aarch64(PSDSPContext *s)
Definition: aacpsdsp_init_aarch64.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:256
PS_AP_LINKS
#define PS_AP_LINKS
Definition: aacps.h:40
AAC_MUL30
#define AAC_MUL30(x, y)
Definition: aac_defines.h:97
AAC_MSUB30
#define AAC_MSUB30(x, y, a, b)
Definition: aac_defines.h:103
ps_stereo_interpolate_ipdopd_c
static void ps_stereo_interpolate_ipdopd_c(INTFLOAT(*l)[2], INTFLOAT(*r)[2], INTFLOAT h[2][4], INTFLOAT h_step[2][4], int len)
Definition: aacpsdsp_template.c:179
ps_add_squares_c
static void ps_add_squares_c(INTFLOAT *dst, const INTFLOAT(*src)[2], int n)
Definition: aacpsdsp_template.c:29
PS_MAX_AP_DELAY
#define PS_MAX_AP_DELAY
Definition: aacps.h:41
f
f
Definition: af_crystalizer.c:122
ps_hybrid_synthesis_deint_c
static void ps_hybrid_synthesis_deint_c(INTFLOAT out[2][38][64], INTFLOAT(*in)[32][2], int i, int len)
Definition: aacpsdsp_template.c:92
ps_hybrid_analysis_c
static void ps_hybrid_analysis_c(INTFLOAT(*out)[2], INTFLOAT(*in)[2], const INTFLOAT(*filter)[8][2], ptrdiff_t stride, int n)
Definition: aacpsdsp_template.c:46
ps_decorrelate_c
static void ps_decorrelate_c(INTFLOAT(*out)[2], INTFLOAT(*delay)[2], INTFLOAT(*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2], const INTFLOAT phi_fract[2], const INTFLOAT(*Q_fract)[2], const INTFLOAT *transient_gain, INTFLOAT g_decay_slope, int len)
Definition: aacpsdsp_template.c:106
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
INT64FLOAT
float INT64FLOAT
Definition: aac_defines.h:84
attributes.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AAC_MADD30_V8
#define AAC_MADD30_V8(x, y, a, b, c, d, e, f)
Definition: aac_defines.h:101
AAC_MUL16
#define AAC_MUL16(x, y)
Definition: aac_defines.h:95
AAC_RENAME
#define AAC_RENAME(x)
Definition: aac_defines.h:79
len
int len
Definition: vorbis_enc_data.h:426
UINTFLOAT
float UINTFLOAT
Definition: aac_defines.h:83
stride
#define stride
Definition: h264pred_template.c:537
ps_mul_pair_single_c
static void ps_mul_pair_single_c(INTFLOAT(*dst)[2], INTFLOAT(*src0)[2], INTFLOAT *src1, int n)
Definition: aacpsdsp_template.c:36
ff_psdsp_init
av_cold void AAC_RENAME() ff_psdsp_init(PSDSPContext *s)
Definition: aacpsdsp_template.c:215
phi_fract
static int phi_fract[2][50][2]
Definition: aacps_fixed_tablegen.h:61
PSDSPContext
Definition: aacpsdsp.h:32
L
#define L(x)
Definition: vpx_arith.h:36
ff_psdsp_init_riscv
void ff_psdsp_init_riscv(PSDSPContext *s)
Definition: aacpsdsp_init.c:40
Q31
#define Q31(x)
Definition: aac_defines.h:92
src0
const pixel *const src0
Definition: h264pred_template.c:420
AAC_MSUB30_V8
#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f)
Definition: aac_defines.h:104
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
h
h
Definition: vp9dsp_template.c:2038
AAC_MADD28
#define AAC_MADD28(x, y, a, b)
Definition: aac_defines.h:99
int
int
Definition: ffmpeg_filter.c:156
INTFLOAT
float INTFLOAT
Definition: aac_defines.h:82