FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aac/aacdec_fixed_prediction.h
Date: 2024-10-04 17:46:48
Exec Total Coverage
Lines: 0 70 0.0%
Functions: 0 5 0.0%
Branches: 0 18 0.0%

Line Branch Exec Source
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
35 static av_always_inline SoftFloat flt16_round(SoftFloat pf)
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
49 static av_always_inline SoftFloat flt16_even(SoftFloat pf)
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
63 static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
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
135 static av_always_inline void reset_predict_state(PredictorState *ps)
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 */
152