FFmpeg
aacdec_fixed_prediction.h
Go to the documentation of this file.
1 /*
2  * AAC decoder
3  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
4  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
5  * Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
6  *
7  * AAC LATM decoder
8  * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
9  * Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
10  *
11  * AAC decoder fixed-point implementation
12  * Copyright (c) 2013
13  * MIPS Technologies, Inc., California.
14  *
15  * This file is part of FFmpeg.
16  *
17  * FFmpeg is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  *
22  * FFmpeg is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25  * Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with FFmpeg; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 
32 #ifndef AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H
33 #define AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H
34 
36 {
37  SoftFloat tmp;
38  int s;
39 
40  tmp.exp = pf.exp;
41  s = pf.mant >> 31;
42  tmp.mant = (pf.mant ^ s) - s;
43  tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
44  tmp.mant = (tmp.mant ^ s) - s;
45 
46  return tmp;
47 }
48 
50 {
51  SoftFloat tmp;
52  int s;
53 
54  tmp.exp = pf.exp;
55  s = pf.mant >> 31;
56  tmp.mant = (pf.mant ^ s) - s;
57  tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
58  tmp.mant = (tmp.mant ^ s) - s;
59 
60  return tmp;
61 }
62 
64 {
65  SoftFloat pun;
66  int s;
67 
68  pun.exp = pf.exp;
69  s = pf.mant >> 31;
70  pun.mant = (pf.mant ^ s) - s;
71  pun.mant = pun.mant & 0xFFC00000U;
72  pun.mant = (pun.mant ^ s) - s;
73 
74  return pun;
75 }
76 
77 static av_always_inline void predict(PredictorState *ps, int *coef,
78  int output_enable)
79 {
80  const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64
81  const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32
82  SoftFloat e0, e1;
83  SoftFloat pv;
84  SoftFloat k1, k2;
85  SoftFloat r0 = ps->r0, r1 = ps->r1;
86  SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
87  SoftFloat var0 = ps->var0, var1 = ps->var1;
88  SoftFloat tmp;
89 
90  if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
91  k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
92  }
93  else {
94  k1.mant = 0;
95  k1.exp = 0;
96  }
97 
98  if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
99  k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
100  }
101  else {
102  k2.mant = 0;
103  k2.exp = 0;
104  }
105 
106  tmp = av_mul_sf(k1, r0);
107  pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
108  if (output_enable) {
109  int shift = 28 - pv.exp;
110 
111  if (shift < 31) {
112  if (shift > 0) {
113  *coef += (unsigned)((pv.mant + (1 << (shift - 1))) >> shift);
114  } else
115  *coef += (unsigned)pv.mant << -shift;
116  }
117  }
118 
119  e0 = av_int2sf(*coef, 2);
120  e1 = av_sub_sf(e0, tmp);
121 
122  ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
123  tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
124  tmp.exp--;
125  ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
126  ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
127  tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
128  tmp.exp--;
129  ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
130 
131  ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
132  ps->r0 = flt16_trunc(av_mul_sf(a, e0));
133 }
134 
136 {
137  ps->r0.mant = 0;
138  ps->r0.exp = 0;
139  ps->r1.mant = 0;
140  ps->r1.exp = 0;
141  ps->cor0.mant = 0;
142  ps->cor0.exp = 0;
143  ps->cor1.mant = 0;
144  ps->cor1.exp = 0;
145  ps->var0.mant = 0x20000000;
146  ps->var0.exp = 1;
147  ps->var1.mant = 0x20000000;
148  ps->var1.exp = 1;
149 }
150 
151 #endif /* AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H */
flt16_trunc
static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
Definition: aacdec_fixed_prediction.h:63
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
av_sub_sf
static av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:173
predict
static av_always_inline void predict(PredictorState *ps, int *coef, int output_enable)
Definition: aacdec_fixed_prediction.h:77
SoftFloat::mant
int32_t mant
Definition: softfloat.h:35
flt16_round
static av_always_inline SoftFloat flt16_round(SoftFloat pf)
Definition: aacdec_fixed_prediction.h:35
PredictorState::var1
float var1
Definition: aac_defines.h:134
av_div_sf
static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b)
b has to be normalized and not zero.
Definition: softfloat.h:116
PredictorState::cor0
float cor0
Definition: aac_defines.h:131
s
#define s(width, name)
Definition: cbs_vp9.c:198
PredictorState
Predictor State.
Definition: aac_defines.h:130
flt16_even
static av_always_inline SoftFloat flt16_even(SoftFloat pf)
Definition: aacdec_fixed_prediction.h:49
SoftFloat::exp
int32_t exp
Definition: softfloat.h:36
reset_predict_state
static av_always_inline void reset_predict_state(PredictorState *ps)
Definition: aacdec_fixed_prediction.h:135
shift
static int shift(int a, int b)
Definition: bonk.c:261
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
SoftFloat
Definition: softfloat.h:34
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
PredictorState::r1
float r1
Definition: aac_defines.h:136
pv
#define pv
Definition: regdef.h:60
PredictorState::var0
float var0
Definition: aac_defines.h:133
U
#define U(x)
Definition: vpx_arith.h:37
PredictorState::r0
float r0
Definition: aac_defines.h:135
av_add_sf
static av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:162
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
av_mul_sf
static av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:102
PredictorState::cor1
float cor1
Definition: aac_defines.h:132