FFmpeg
aacdec_mips.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012
3  * MIPS Technologies, Inc., California.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Authors: Darko Laus (darko@mips.com)
30  * Djordje Pesut (djordje@mips.com)
31  * Mirjana Vulin (mvulin@mips.com)
32  *
33  * This file is part of FFmpeg.
34  *
35  * FFmpeg is free software; you can redistribute it and/or
36  * modify it under the terms of the GNU Lesser General Public
37  * License as published by the Free Software Foundation; either
38  * version 2.1 of the License, or (at your option) any later version.
39  *
40  * FFmpeg is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43  * Lesser General Public License for more details.
44  *
45  * You should have received a copy of the GNU Lesser General Public
46  * License along with FFmpeg; if not, write to the Free Software
47  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
48  */
49 
50 /**
51  * @file
52  * Reference: libavcodec/aacdec.c
53  */
54 
55 #include "libavcodec/aac.h"
56 #include "aacdec_mips.h"
57 #include "libavcodec/aactab.h"
58 #include "libavcodec/sinewin.h"
59 #include "libavutil/mips/asmdefs.h"
60 
61 #if HAVE_INLINE_ASM
62 static av_always_inline void float_copy(float *dst, const float *src, int count)
63 {
64  // Copy 'count' floats from src to dst
65  const float *loop_end = src + count;
66  int temp[8];
67 
68  // count must be a multiple of 8
69  av_assert2(count % 8 == 0);
70 
71  // loop unrolled 8 times
72  __asm__ volatile (
73  ".set push \n\t"
74  ".set noreorder \n\t"
75  "1: \n\t"
76  "lw %[temp0], 0(%[src]) \n\t"
77  "lw %[temp1], 4(%[src]) \n\t"
78  "lw %[temp2], 8(%[src]) \n\t"
79  "lw %[temp3], 12(%[src]) \n\t"
80  "lw %[temp4], 16(%[src]) \n\t"
81  "lw %[temp5], 20(%[src]) \n\t"
82  "lw %[temp6], 24(%[src]) \n\t"
83  "lw %[temp7], 28(%[src]) \n\t"
84  PTR_ADDIU "%[src], %[src], 32 \n\t"
85  "sw %[temp0], 0(%[dst]) \n\t"
86  "sw %[temp1], 4(%[dst]) \n\t"
87  "sw %[temp2], 8(%[dst]) \n\t"
88  "sw %[temp3], 12(%[dst]) \n\t"
89  "sw %[temp4], 16(%[dst]) \n\t"
90  "sw %[temp5], 20(%[dst]) \n\t"
91  "sw %[temp6], 24(%[dst]) \n\t"
92  "sw %[temp7], 28(%[dst]) \n\t"
93  "bne %[src], %[loop_end], 1b \n\t"
94  PTR_ADDIU "%[dst], %[dst], 32 \n\t"
95  ".set pop \n\t"
96 
97  : [temp0]"=&r"(temp[0]), [temp1]"=&r"(temp[1]),
98  [temp2]"=&r"(temp[2]), [temp3]"=&r"(temp[3]),
99  [temp4]"=&r"(temp[4]), [temp5]"=&r"(temp[5]),
100  [temp6]"=&r"(temp[6]), [temp7]"=&r"(temp[7]),
101  [src]"+r"(src), [dst]"+r"(dst)
102  : [loop_end]"r"(loop_end)
103  : "memory"
104  );
105 }
106 
107 static av_always_inline int lcg_random(unsigned previous_val)
108 {
109  union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
110  return v.s;
111 }
112 
113 static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce)
114 {
115  IndividualChannelStream *ics = &sce->ics;
116  float *in = sce->coeffs;
117  float *out = sce->ret;
118  float *saved = sce->saved;
119  const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
120  const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
121  const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
122  float *buf = ac->buf_mdct;
123  int i;
124 
125  if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
126  for (i = 0; i < 1024; i += 128)
127  ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
128  } else
129  ac->mdct.imdct_half(&ac->mdct, buf, in);
130 
131  /* window overlapping
132  * NOTE: To simplify the overlapping code, all 'meaningless' short to long
133  * and long to short transitions are considered to be short to short
134  * transitions. This leaves just two cases (long to long and short to short)
135  * with a little special sauce for EIGHT_SHORT_SEQUENCE.
136  */
137  if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
139  ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
140  } else {
141  float_copy(out, saved, 448);
142 
143  if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
144  {
145  float wi;
146  float wj;
147  int i;
148  float temp0, temp1, temp2, temp3;
149  float *dst0 = out + 448 + 0*128;
150  float *dst1 = dst0 + 64 + 63;
151  float *dst2 = saved + 63;
152  float *win0 = (float*)swindow;
153  float *win1 = win0 + 64 + 63;
154  float *win0_prev = (float*)swindow_prev;
155  float *win1_prev = win0_prev + 64 + 63;
156  float *src0_prev = saved + 448;
157  float *src1_prev = buf + 0*128 + 63;
158  float *src0 = buf + 0*128 + 64;
159  float *src1 = buf + 1*128 + 63;
160 
161  for(i = 0; i < 64; i++)
162  {
163  temp0 = src0_prev[0];
164  temp1 = src1_prev[0];
165  wi = *win0_prev;
166  wj = *win1_prev;
167  temp2 = src0[0];
168  temp3 = src1[0];
169  dst0[0] = temp0 * wj - temp1 * wi;
170  dst1[0] = temp0 * wi + temp1 * wj;
171 
172  wi = *win0;
173  wj = *win1;
174 
175  temp0 = src0[128];
176  temp1 = src1[128];
177  dst0[128] = temp2 * wj - temp3 * wi;
178  dst1[128] = temp2 * wi + temp3 * wj;
179 
180  temp2 = src0[256];
181  temp3 = src1[256];
182  dst0[256] = temp0 * wj - temp1 * wi;
183  dst1[256] = temp0 * wi + temp1 * wj;
184  dst0[384] = temp2 * wj - temp3 * wi;
185  dst1[384] = temp2 * wi + temp3 * wj;
186 
187  temp0 = src0[384];
188  temp1 = src1[384];
189  dst0[512] = temp0 * wj - temp1 * wi;
190  dst2[0] = temp0 * wi + temp1 * wj;
191 
192  src0++;
193  src1--;
194  src0_prev++;
195  src1_prev--;
196  win0++;
197  win1--;
198  win0_prev++;
199  win1_prev--;
200  dst0++;
201  dst1--;
202  dst2--;
203  }
204  }
205  } else {
206  ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
207  float_copy(out + 576, buf + 64, 448);
208  }
209  }
210 
211  // buffer update
212  if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
213  ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
214  ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
215  ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
216  float_copy(saved + 448, buf + 7*128 + 64, 64);
217  } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
218  float_copy(saved, buf + 512, 448);
219  float_copy(saved + 448, buf + 7*128 + 64, 64);
220  } else { // LONG_STOP or ONLY_LONG
221  float_copy(saved, buf + 512, 512);
222  }
223 }
224 
225 static void apply_ltp_mips(AACContext *ac, SingleChannelElement *sce)
226 {
227  const LongTermPrediction *ltp = &sce->ics.ltp;
228  const uint16_t *offsets = sce->ics.swb_offset;
229  int i, sfb;
230  int j, k;
231 
232  if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
233  float *predTime = sce->ret;
234  float *predFreq = ac->buf_mdct;
235  float *p_predTime;
236  int16_t num_samples = 2048;
237 
238  if (ltp->lag < 1024)
239  num_samples = ltp->lag + 1024;
240  j = (2048 - num_samples) >> 2;
241  k = (2048 - num_samples) & 3;
242  p_predTime = &predTime[num_samples];
243 
244  for (i = 0; i < num_samples; i++)
245  predTime[i] = sce->ltp_state[i + 2048 - ltp->lag] * ltp->coef;
246  for (i = 0; i < j; i++) {
247 
248  /* loop unrolled 4 times */
249  __asm__ volatile (
250  "sw $0, 0(%[p_predTime]) \n\t"
251  "sw $0, 4(%[p_predTime]) \n\t"
252  "sw $0, 8(%[p_predTime]) \n\t"
253  "sw $0, 12(%[p_predTime]) \n\t"
254  PTR_ADDIU "%[p_predTime], %[p_predTime], 16 \n\t"
255 
256  : [p_predTime]"+r"(p_predTime)
257  :
258  : "memory"
259  );
260  }
261  for (i = 0; i < k; i++) {
262 
263  __asm__ volatile (
264  "sw $0, 0(%[p_predTime]) \n\t"
265  PTR_ADDIU "%[p_predTime], %[p_predTime], 4 \n\t"
266 
267  : [p_predTime]"+r"(p_predTime)
268  :
269  : "memory"
270  );
271  }
272 
273  ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
274 
275  if (sce->tns.present)
276  ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
277 
278  for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
279  if (ltp->used[sfb])
280  for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
281  sce->coeffs[i] += predFreq[i];
282  }
283 }
284 
285 #if HAVE_MIPSFPU
286 static av_always_inline void fmul_and_reverse(float *dst, const float *src0, const float *src1, int count)
287 {
288  /* Multiply 'count' floats in src0 by src1 and store the results in dst in reverse */
289  /* This should be equivalent to a normal fmul, followed by reversing dst */
290 
291  // count must be a multiple of 4
292  av_assert2(count % 4 == 0);
293 
294  // move src0 and src1 to the last element of their arrays
295  src0 += count - 1;
296  src1 += count - 1;
297 
298  for (; count > 0; count -= 4){
299  float temp[12];
300 
301  /* loop unrolled 4 times */
302  __asm__ volatile (
303  "lwc1 %[temp0], 0(%[ptr2]) \n\t"
304  "lwc1 %[temp1], -4(%[ptr2]) \n\t"
305  "lwc1 %[temp2], -8(%[ptr2]) \n\t"
306  "lwc1 %[temp3], -12(%[ptr2]) \n\t"
307  "lwc1 %[temp4], 0(%[ptr3]) \n\t"
308  "lwc1 %[temp5], -4(%[ptr3]) \n\t"
309  "lwc1 %[temp6], -8(%[ptr3]) \n\t"
310  "lwc1 %[temp7], -12(%[ptr3]) \n\t"
311  "mul.s %[temp8], %[temp0], %[temp4] \n\t"
312  "mul.s %[temp9], %[temp1], %[temp5] \n\t"
313  "mul.s %[temp10], %[temp2], %[temp6] \n\t"
314  "mul.s %[temp11], %[temp3], %[temp7] \n\t"
315  "swc1 %[temp8], 0(%[ptr1]) \n\t"
316  "swc1 %[temp9], 4(%[ptr1]) \n\t"
317  "swc1 %[temp10], 8(%[ptr1]) \n\t"
318  "swc1 %[temp11], 12(%[ptr1]) \n\t"
319  PTR_ADDIU "%[ptr1], %[ptr1], 16 \n\t"
320  PTR_ADDIU "%[ptr2], %[ptr2], -16 \n\t"
321  PTR_ADDIU "%[ptr3], %[ptr3], -16 \n\t"
322 
323  : [temp0]"=&f"(temp[0]), [temp1]"=&f"(temp[1]),
324  [temp2]"=&f"(temp[2]), [temp3]"=&f"(temp[3]),
325  [temp4]"=&f"(temp[4]), [temp5]"=&f"(temp[5]),
326  [temp6]"=&f"(temp[6]), [temp7]"=&f"(temp[7]),
327  [temp8]"=&f"(temp[8]), [temp9]"=&f"(temp[9]),
328  [temp10]"=&f"(temp[10]), [temp11]"=&f"(temp[11]),
329  [ptr1]"+r"(dst), [ptr2]"+r"(src0), [ptr3]"+r"(src1)
330  :
331  : "memory"
332  );
333  }
334 }
335 
336 static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce)
337 {
338  IndividualChannelStream *ics = &sce->ics;
339  float *saved = sce->saved;
340  float *saved_ltp = sce->coeffs;
341  const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
342  const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
343  float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
344 
345  if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
346  float *p_saved_ltp = saved_ltp + 576;
347  float *loop_end1 = p_saved_ltp + 448;
348 
349  float_copy(saved_ltp, saved, 512);
350 
351  /* loop unrolled 8 times */
352  __asm__ volatile (
353  "1: \n\t"
354  "sw $0, 0(%[p_saved_ltp]) \n\t"
355  "sw $0, 4(%[p_saved_ltp]) \n\t"
356  "sw $0, 8(%[p_saved_ltp]) \n\t"
357  "sw $0, 12(%[p_saved_ltp]) \n\t"
358  "sw $0, 16(%[p_saved_ltp]) \n\t"
359  "sw $0, 20(%[p_saved_ltp]) \n\t"
360  "sw $0, 24(%[p_saved_ltp]) \n\t"
361  "sw $0, 28(%[p_saved_ltp]) \n\t"
362  PTR_ADDIU "%[p_saved_ltp],%[p_saved_ltp], 32 \n\t"
363  "bne %[p_saved_ltp], %[loop_end1], 1b \n\t"
364 
365  : [p_saved_ltp]"+r"(p_saved_ltp)
366  : [loop_end1]"r"(loop_end1)
367  : "memory"
368  );
369 
370  ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
371  fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 960, swindow, 64);
372  } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
373  float *buff0 = saved;
374  float *buff1 = saved_ltp;
375  float *loop_end = saved + 448;
376 
377  /* loop unrolled 8 times */
378  __asm__ volatile (
379  ".set push \n\t"
380  ".set noreorder \n\t"
381  "1: \n\t"
382  "lw %[temp0], 0(%[src]) \n\t"
383  "lw %[temp1], 4(%[src]) \n\t"
384  "lw %[temp2], 8(%[src]) \n\t"
385  "lw %[temp3], 12(%[src]) \n\t"
386  "lw %[temp4], 16(%[src]) \n\t"
387  "lw %[temp5], 20(%[src]) \n\t"
388  "lw %[temp6], 24(%[src]) \n\t"
389  "lw %[temp7], 28(%[src]) \n\t"
390  PTR_ADDIU "%[src], %[src], 32 \n\t"
391  "sw %[temp0], 0(%[dst]) \n\t"
392  "sw %[temp1], 4(%[dst]) \n\t"
393  "sw %[temp2], 8(%[dst]) \n\t"
394  "sw %[temp3], 12(%[dst]) \n\t"
395  "sw %[temp4], 16(%[dst]) \n\t"
396  "sw %[temp5], 20(%[dst]) \n\t"
397  "sw %[temp6], 24(%[dst]) \n\t"
398  "sw %[temp7], 28(%[dst]) \n\t"
399  "sw $0, 2304(%[dst]) \n\t"
400  "sw $0, 2308(%[dst]) \n\t"
401  "sw $0, 2312(%[dst]) \n\t"
402  "sw $0, 2316(%[dst]) \n\t"
403  "sw $0, 2320(%[dst]) \n\t"
404  "sw $0, 2324(%[dst]) \n\t"
405  "sw $0, 2328(%[dst]) \n\t"
406  "sw $0, 2332(%[dst]) \n\t"
407  "bne %[src], %[loop_end], 1b \n\t"
408  PTR_ADDIU "%[dst], %[dst], 32 \n\t"
409  ".set pop \n\t"
410 
411  : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
412  [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
413  [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
414  [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
415  [src]"+r"(buff0), [dst]"+r"(buff1)
416  : [loop_end]"r"(loop_end)
417  : "memory"
418  );
419  ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
420  fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 960, swindow, 64);
421  } else { // LONG_STOP or ONLY_LONG
422  ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
423  fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 512, lwindow, 512);
424  }
425 
426  float_copy(sce->ltp_state, sce->ltp_state + 1024, 1024);
427  float_copy(sce->ltp_state + 1024, sce->ret, 1024);
428  float_copy(sce->ltp_state + 2048, saved_ltp, 1024);
429 }
430 #endif /* HAVE_MIPSFPU */
431 #endif /* HAVE_INLINE_ASM */
432 
434 {
435 #if HAVE_INLINE_ASM
436  c->imdct_and_windowing = imdct_and_windowing_mips;
437  c->apply_ltp = apply_ltp_mips;
438 #if HAVE_MIPSFPU
439  c->update_ltp = update_ltp_mips;
440 #endif /* HAVE_MIPSFPU */
441 #endif /* HAVE_INLINE_ASM */
442 }
AVFloatDSPContext * fdsp
Definition: aac.h:333
uint8_t use_kb_window[2]
If set, use Kaiser-Bessel window, otherwise use a sine window.
Definition: aac.h:177
INTFLOAT buf_mdct[1024]
Definition: aac.h:316
MIPS assembly defines from sys/asm.h but rewritten for use with C inline assembly (rather than from w...
else temp
Definition: vf_mcdeint.c:256
INTFLOAT * ret
PCM output.
Definition: aac.h:269
#define MAX_LTP_LONG_SFB
Definition: aac.h:51
Reference: libavcodec/aacdec.c.
#define src
Definition: vp8dsp.c:254
static av_always_inline int lcg_random(unsigned previous_val)
linear congruential pseudorandom number generator
const uint16_t * swb_offset
table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular wind...
Definition: aac.h:181
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
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
TemporalNoiseShaping tns
Definition: aac.h:250
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
void(* vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len)
Overlap/add with window function.
Definition: float_dsp.h:119
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
FFTContext mdct_small
Definition: aac.h:324
float ff_aac_kbd_long_1024[1024]
Definition: aactab.c:38
void(* apply_ltp)(AACContext *ac, SingleChannelElement *sce)
Definition: aac.h:364
uint8_t max_sfb
number of scalefactor bands per group
Definition: aac.h:175
GLsizei count
Definition: opengl_enc.c:108
void(* apply_tns)(INTFLOAT coef[1024], TemporalNoiseShaping *tns, IndividualChannelStream *ics, int decode)
Definition: aac.h:365
enum WindowSequence window_sequence[2]
Definition: aac.h:176
INTFLOAT ltp_state[3072]
time signal for LTP
Definition: aac.h:265
#define FFMIN(a, b)
Definition: common.h:96
#define s(width, name)
Definition: cbs_vp9.c:257
AAC definitions and structures.
#define src1
Definition: h264pred.c:139
float ff_aac_kbd_short_128[128]
Definition: aactab.c:39
Long Term Prediction.
Definition: aac.h:163
IndividualChannelStream ics
Definition: aac.h:249
void * buf
Definition: avisynth_c.h:766
#define PTR_ADDIU
Definition: asmdefs.h:48
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
#define src0
Definition: h264pred.c:138
main AAC context
Definition: aac.h:293
LongTermPrediction ltp
Definition: aac.h:180
void(* imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.h:108
INTFLOAT coeffs[1024]
coefficients for IMDCT, maybe processed
Definition: aac.h:262
int16_t lag
Definition: aac.h:165
INTFLOAT saved[1536]
overlap
Definition: aac.h:263
Single Channel Element - used for both SCE and LFE elements.
Definition: aac.h:248
Individual Channel Stream.
Definition: aac.h:174
INTFLOAT coef
Definition: aac.h:167
void(* update_ltp)(AACContext *ac, SingleChannelElement *sce)
Definition: aac.h:369
void(* windowing_and_mdct_ltp)(AACContext *ac, INTFLOAT *out, INTFLOAT *in, IndividualChannelStream *ics)
Definition: aac.h:367
FILE * out
Definition: movenc.c:54
FFTContext mdct
Definition: aac.h:323
#define av_always_inline
Definition: attributes.h:39
void(* imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce)
Definition: aac.h:363
int8_t used[MAX_LTP_LONG_SFB]
Definition: aac.h:168
void ff_aacdec_init_mips(AACContext *c)
Definition: aacdec_mips.c:433
AAC data declarations.
for(j=16;j >0;--j)
void(* vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len)
Calculate the entry wise product of two vectors of floats, and store the result in a vector of floats...
Definition: float_dsp.h:154