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 *restrict dst,
30  const INTFLOAT (*src)[2], int n)
31 {
32  for (int 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 (*restrict dst)[2],
37  INTFLOAT (*src0)[2], INTFLOAT *src1,
38  int n)
39 {
40  for (int 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 (*restrict out)[2],
47  INTFLOAT (*in)[2],
48  const INTFLOAT (*filter)[8][2],
49  ptrdiff_t stride, int n)
50 {
51  INT64FLOAT inre0[6], inre1[6], inim0[6], inim1[6];
52 
53  for (int j = 0; j < 6; j++) {
54  inre0[j] = in[j][0] + in[12 - j][0];
55  inre1[j] = in[j][1] - in[12 - j][1];
56  inim0[j] = in[j][1] + in[12 - j][1];
57  inim1[j] = in[j][0] - in[12 - j][0];
58  }
59 
60  for (int i = 0; i < n; i++) {
61  INT64FLOAT sum_re = (INT64FLOAT)filter[i][6][0] * in[6][0];
62  INT64FLOAT sum_im = (INT64FLOAT)filter[i][6][0] * in[6][1];
63 
64  for (int j = 0; j < 6; j++) {
65  sum_re += (INT64FLOAT)filter[i][j][0] * inre0[j] -
66  (INT64FLOAT)filter[i][j][1] * inre1[j];
67  sum_im += (INT64FLOAT)filter[i][j][0] * inim0[j] +
68  (INT64FLOAT)filter[i][j][1] * inim1[j];
69  }
70 #if USE_FIXED
71  out[i * stride][0] = (int)((sum_re + 0x40000000) >> 31);
72  out[i * stride][1] = (int)((sum_im + 0x40000000) >> 31);
73 #else
74  out[i * stride][0] = sum_re;
75  out[i * stride][1] = sum_im;
76 #endif /* USE_FIXED */
77  }
78 }
79 
80 static void ps_hybrid_analysis_ileave_c(INTFLOAT (*restrict out)[32][2],
81  INTFLOAT L[2][38][64],
82  int i, int len)
83 {
84  for (; i < 64; i++) {
85  for (int 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 (*restrict in)[32][2],
94  int i, int len)
95 {
96  for (; i < 64; i++) {
97  for (int n = 0; n < len; n++) {
98  out[0][n][i] = in[i][n][0];
99  out[1][n][i] = in[i][n][1];
100  }
101  }
102 }
103 
104 static void ps_decorrelate_c(INTFLOAT (*out)[2], INTFLOAT (*delay)[2],
105  INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
106  const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2],
107  const INTFLOAT *transient_gain,
108  INTFLOAT g_decay_slope,
109  int len)
110 {
111  static const INTFLOAT a[] = { Q31(0.65143905753106f),
112  Q31(0.56471812200776f),
113  Q31(0.48954165955695f) };
114  INTFLOAT ag[PS_AP_LINKS];
115  int m, n;
116 
117  for (m = 0; m < PS_AP_LINKS; m++)
118  ag[m] = AAC_MUL30(a[m], g_decay_slope);
119 
120  for (n = 0; n < len; n++) {
121  INTFLOAT in_re = AAC_MSUB30(delay[n][0], phi_fract[0], delay[n][1], phi_fract[1]);
122  INTFLOAT in_im = AAC_MADD30(delay[n][0], phi_fract[1], delay[n][1], phi_fract[0]);
123  for (m = 0; m < PS_AP_LINKS; m++) {
124  INTFLOAT a_re = AAC_MUL31(ag[m], in_re);
125  INTFLOAT a_im = AAC_MUL31(ag[m], in_im);
126  INTFLOAT link_delay_re = ap_delay[m][n+2-m][0];
127  INTFLOAT link_delay_im = ap_delay[m][n+2-m][1];
128  INTFLOAT fractional_delay_re = Q_fract[m][0];
129  INTFLOAT fractional_delay_im = Q_fract[m][1];
130  INTFLOAT apd_re = in_re;
131  INTFLOAT apd_im = in_im;
132  in_re = AAC_MSUB30(link_delay_re, fractional_delay_re,
133  link_delay_im, fractional_delay_im);
134  in_re -= (UINTFLOAT)a_re;
135  in_im = AAC_MADD30(link_delay_re, fractional_delay_im,
136  link_delay_im, fractional_delay_re);
137  in_im -= (UINTFLOAT)a_im;
138  ap_delay[m][n+5][0] = apd_re + (UINTFLOAT)AAC_MUL31(ag[m], in_re);
139  ap_delay[m][n+5][1] = apd_im + (UINTFLOAT)AAC_MUL31(ag[m], in_im);
140  }
141  out[n][0] = AAC_MUL16(transient_gain[n], in_re);
142  out[n][1] = AAC_MUL16(transient_gain[n], in_im);
143  }
144 }
145 
146 static void ps_stereo_interpolate_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2],
147  INTFLOAT h[2][4], INTFLOAT h_step[2][4],
148  int len)
149 {
150  INTFLOAT h0 = h[0][0];
151  INTFLOAT h1 = h[0][1];
152  INTFLOAT h2 = h[0][2];
153  INTFLOAT h3 = h[0][3];
154  UINTFLOAT hs0 = h_step[0][0];
155  UINTFLOAT hs1 = h_step[0][1];
156  UINTFLOAT hs2 = h_step[0][2];
157  UINTFLOAT hs3 = h_step[0][3];
158  int n;
159 
160  for (n = 0; n < len; n++) {
161  //l is s, r is d
162  INTFLOAT l_re = l[n][0];
163  INTFLOAT l_im = l[n][1];
164  INTFLOAT r_re = r[n][0];
165  INTFLOAT r_im = r[n][1];
166  h0 += hs0;
167  h1 += hs1;
168  h2 += hs2;
169  h3 += hs3;
170  l[n][0] = AAC_MADD30(h0, l_re, h2, r_re);
171  l[n][1] = AAC_MADD30(h0, l_im, h2, r_im);
172  r[n][0] = AAC_MADD30(h1, l_re, h3, r_re);
173  r[n][1] = AAC_MADD30(h1, l_im, h3, r_im);
174  }
175 }
176 
178  INTFLOAT h[2][4], INTFLOAT h_step[2][4],
179  int len)
180 {
181  INTFLOAT h00 = h[0][0], h10 = h[1][0];
182  INTFLOAT h01 = h[0][1], h11 = h[1][1];
183  INTFLOAT h02 = h[0][2], h12 = h[1][2];
184  INTFLOAT h03 = h[0][3], h13 = h[1][3];
185  UINTFLOAT hs00 = h_step[0][0], hs10 = h_step[1][0];
186  UINTFLOAT hs01 = h_step[0][1], hs11 = h_step[1][1];
187  UINTFLOAT hs02 = h_step[0][2], hs12 = h_step[1][2];
188  UINTFLOAT hs03 = h_step[0][3], hs13 = h_step[1][3];
189  int n;
190 
191  for (n = 0; n < len; n++) {
192  //l is s, r is d
193  INTFLOAT l_re = l[n][0];
194  INTFLOAT l_im = l[n][1];
195  INTFLOAT r_re = r[n][0];
196  INTFLOAT r_im = r[n][1];
197  h00 += hs00;
198  h01 += hs01;
199  h02 += hs02;
200  h03 += hs03;
201  h10 += hs10;
202  h11 += hs11;
203  h12 += hs12;
204  h13 += hs13;
205 
206  l[n][0] = AAC_MSUB30_V8(h00, l_re, h02, r_re, h10, l_im, h12, r_im);
207  l[n][1] = AAC_MADD30_V8(h00, l_im, h02, r_im, h10, l_re, h12, r_re);
208  r[n][0] = AAC_MSUB30_V8(h01, l_re, h03, r_re, h11, l_im, h13, r_im);
209  r[n][1] = AAC_MADD30_V8(h01, l_im, h03, r_im, h11, l_re, h13, r_re);
210  }
211 }
212 
214 {
215  s->add_squares = ps_add_squares_c;
216  s->mul_pair_single = ps_mul_pair_single_c;
217  s->hybrid_analysis = ps_hybrid_analysis_c;
218  s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c;
219  s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c;
220  s->decorrelate = ps_decorrelate_c;
221  s->stereo_interpolate[0] = ps_stereo_interpolate_c;
222  s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c;
223 
224 #if !USE_FIXED
225 #if ARCH_ARM
227 #elif ARCH_AARCH64
229 #elif ARCH_MIPS
231 #elif ARCH_RISCV
233 #elif ARCH_X86
235 #endif
236 #endif /* !USE_FIXED */
237 }
AAC_MADD30
#define AAC_MADD30(x, y, a, b)
Definition: aac_defines.h:106
h0
static const float h0[64]
Definition: speexdata.h:741
r
const char * r
Definition: vf_curves.c:126
ps_hybrid_analysis_c
static void ps_hybrid_analysis_c(INTFLOAT(*restrict out)[2], INTFLOAT(*in)[2], const INTFLOAT(*filter)[8][2], ptrdiff_t stride, int n)
Definition: aacpsdsp_template.c:46
out
FILE * out
Definition: movenc.c:54
ps_add_squares_c
static void ps_add_squares_c(INTFLOAT *restrict dst, const INTFLOAT(*src)[2], int n)
Definition: aacpsdsp_template.c:29
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_hybrid_analysis_ileave_c
static void ps_hybrid_analysis_ileave_c(INTFLOAT(*restrict out)[32][2], INTFLOAT L[2][38][64], int i, int len)
Definition: aacpsdsp_template.c:80
PS_QMF_TIME_SLOTS
#define PS_QMF_TIME_SLOTS
Definition: aacps.h:37
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:146
ff_psdsp_init_arm
void ff_psdsp_init_arm(PSDSPContext *s)
Definition: aacpsdsp_init_arm.c:46
ps_mul_pair_single_c
static void ps_mul_pair_single_c(INTFLOAT(*restrict dst)[2], INTFLOAT(*src0)[2], INTFLOAT *src1, int n)
Definition: aacpsdsp_template.c:36
av_cold
#define av_cold
Definition: attributes.h:90
aacpsdsp.h
AAC_MUL31
#define AAC_MUL31(x, y)
Definition: aac_defines.h:104
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:198
PS_AP_LINKS
#define PS_AP_LINKS
Definition: aacps.h:39
AAC_MUL30
#define AAC_MUL30(x, y)
Definition: aac_defines.h:103
AAC_MSUB30
#define AAC_MSUB30(x, y, a, b)
Definition: aac_defines.h:109
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:177
PS_MAX_AP_DELAY
#define PS_MAX_AP_DELAY
Definition: aacps.h:40
f
f
Definition: af_crystalizer.c:121
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:104
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:90
attributes.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AAC_MADD30_V8
#define AAC_MADD30_V8(x, y, a, b, c, d, e, f)
Definition: aac_defines.h:107
AAC_MUL16
#define AAC_MUL16(x, y)
Definition: aac_defines.h:101
AAC_RENAME
#define AAC_RENAME(x)
Definition: aac_defines.h:86
len
int len
Definition: vorbis_enc_data.h:426
UINTFLOAT
float UINTFLOAT
Definition: aac_defines.h:89
stride
#define stride
Definition: h264pred_template.c:537
ff_psdsp_init
av_cold void AAC_RENAME() ff_psdsp_init(PSDSPContext *s)
Definition: aacpsdsp_template.c:213
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:98
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:110
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:105
int
int
Definition: ffmpeg_filter.c:410
INTFLOAT
float INTFLOAT
Definition: aac_defines.h:88
ps_hybrid_synthesis_deint_c
static void ps_hybrid_synthesis_deint_c(INTFLOAT out[2][38][64], INTFLOAT(*restrict in)[32][2], int i, int len)
Definition: aacpsdsp_template.c:92