/src/ffmpeg/libavcodec/vorbis.c
Line | Count | Source |
1 | | /** |
2 | | * @file |
3 | | * Common code for Vorbis I encoder and decoder |
4 | | * @author Denes Balatoni ( dbalatoni programozo hu ) |
5 | | * |
6 | | * This file is part of FFmpeg. |
7 | | * |
8 | | * FFmpeg is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * FFmpeg is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public |
19 | | * License along with FFmpeg; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | /** |
24 | | * @file |
25 | | * Common code for Vorbis I encoder and decoder |
26 | | * @author Denes Balatoni ( dbalatoni programozo hu ) |
27 | | */ |
28 | | |
29 | | #include "libavutil/common.h" |
30 | | #include "libavutil/error.h" |
31 | | #include "libavutil/log.h" |
32 | | #include "libavutil/macros.h" |
33 | | |
34 | | #include "vorbis.h" |
35 | | #include "vorbis_data.h" |
36 | | |
37 | | |
38 | | /* Helper functions */ |
39 | | |
40 | | // x^(1/n) |
41 | | unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) |
42 | 1.51k | { |
43 | 1.51k | unsigned int ret = 0, i, j; |
44 | | |
45 | 378k | do { |
46 | 378k | ++ret; |
47 | 414k | for (i = 0, j = ret; i < n - 1; i++) |
48 | 36.2k | j *= ret; |
49 | 378k | } while (j <= x); |
50 | | |
51 | 1.51k | return ret - 1; |
52 | 1.51k | } |
53 | | |
54 | | // Generate vlc codes from vorbis huffman code lengths |
55 | | |
56 | | // the two bits[p] > 32 checks should be redundant, all calling code should |
57 | | // already ensure that, but since it allows overwriting the stack it seems |
58 | | // reasonable to check redundantly. |
59 | | int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) |
60 | 18.7k | { |
61 | 18.7k | uint32_t exit_at_level[33] = { 404 }; |
62 | 18.7k | unsigned i, j, p, code; |
63 | | |
64 | 166k | for (p = 0; (p < num) && (bits[p] == 0); ++p) |
65 | 147k | ; |
66 | 18.7k | if (p == num) |
67 | 1.30k | return 0; |
68 | | |
69 | 17.4k | codes[p] = 0; |
70 | 17.4k | if (bits[p] > 32) |
71 | 0 | return AVERROR_INVALIDDATA; |
72 | 257k | for (i = 0; i < bits[p]; ++i) |
73 | 240k | exit_at_level[i+1] = 1u << i; |
74 | | |
75 | 17.4k | ++p; |
76 | | |
77 | 246k | for (i = p; (i < num) && (bits[i] == 0); ++i) |
78 | 229k | ; |
79 | 17.4k | if (i == num) |
80 | 16.2k | return 0; |
81 | | |
82 | 3.88M | for (; p < num; ++p) { |
83 | 3.87M | if (bits[p] > 32) |
84 | 0 | return AVERROR_INVALIDDATA; |
85 | 3.87M | if (bits[p] == 0) |
86 | 3.73M | continue; |
87 | | // find corresponding exit(node which the tree can grow further from) |
88 | 285k | for (i = bits[p]; i > 0; --i) |
89 | 284k | if (exit_at_level[i]) |
90 | 141k | break; |
91 | 141k | if (!i) // overspecified tree |
92 | 677 | return AVERROR_INVALIDDATA; |
93 | 141k | code = exit_at_level[i]; |
94 | 141k | exit_at_level[i] = 0; |
95 | | // construct code (append 0s to end) and introduce new exits |
96 | 283k | for (j = i + 1 ;j <= bits[p]; ++j) |
97 | 142k | exit_at_level[j] = code + (1u << (j - 1)); |
98 | 141k | codes[p] = code; |
99 | 141k | } |
100 | | |
101 | | //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC) |
102 | 9.25k | for (p = 1; p < 33; p++) |
103 | 8.98k | if (exit_at_level[p]) |
104 | 238 | return AVERROR_INVALIDDATA; |
105 | | |
106 | 271 | return 0; |
107 | 509 | } |
108 | | |
109 | | int ff_vorbis_ready_floor1_list(void *logctx, |
110 | | vorbis_floor1_entry *list, int values) |
111 | 12.4k | { |
112 | 12.4k | int i; |
113 | 12.4k | list[0].sort = 0; |
114 | 12.4k | list[1].sort = 1; |
115 | 17.2k | for (i = 2; i < values; i++) { |
116 | 4.75k | int j; |
117 | 4.75k | list[i].low = 0; |
118 | 4.75k | list[i].high = 1; |
119 | 4.75k | list[i].sort = i; |
120 | 32.0k | for (j = 2; j < i; j++) { |
121 | 27.3k | int tmp = list[j].x; |
122 | 27.3k | if (tmp < list[i].x) { |
123 | 13.9k | if (tmp > list[list[i].low].x) |
124 | 3.17k | list[i].low = j; |
125 | 13.9k | } else { |
126 | 13.4k | if (tmp < list[list[i].high].x) |
127 | 1.50k | list[i].high = j; |
128 | 13.4k | } |
129 | 27.3k | } |
130 | 4.75k | } |
131 | 28.0k | for (i = 0; i < values - 1; i++) { |
132 | 15.9k | int j; |
133 | 38.5k | for (j = i + 1; j < values; j++) { |
134 | 23.0k | if (list[i].x == list[j].x) { |
135 | 382 | av_log(logctx, AV_LOG_ERROR, |
136 | 382 | "Duplicate value found in floor 1 X coordinates\n"); |
137 | 382 | return AVERROR_INVALIDDATA; |
138 | 382 | } |
139 | 22.6k | if (list[list[i].sort].x > list[list[j].sort].x) { |
140 | 3.50k | int tmp = list[i].sort; |
141 | 3.50k | list[i].sort = list[j].sort; |
142 | 3.50k | list[j].sort = tmp; |
143 | 3.50k | } |
144 | 22.6k | } |
145 | 15.9k | } |
146 | 12.0k | return 0; |
147 | 12.4k | } |
148 | | |
149 | | static inline void render_line_unrolled(intptr_t x, int y, int x1, |
150 | | intptr_t sy, int ady, int adx, |
151 | | float *buf) |
152 | 72.4k | { |
153 | 72.4k | int err = -adx; |
154 | 72.4k | x -= x1 - 1; |
155 | 72.4k | buf += x1 - 1; |
156 | 971k | while (++x < 0) { |
157 | 899k | err += ady; |
158 | 899k | if (err >= 0) { |
159 | 139k | err += ady - adx; |
160 | 139k | y += sy; |
161 | 139k | buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; |
162 | 139k | } |
163 | 899k | buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; |
164 | 899k | } |
165 | 72.4k | if (x <= 0) { |
166 | 9.12k | if (err + ady >= 0) |
167 | 0 | y += sy; |
168 | 9.12k | buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; |
169 | 9.12k | } |
170 | 72.4k | } |
171 | | |
172 | | static void render_line(int x0, int y0, int x1, int y1, float *buf) |
173 | 451k | { |
174 | 451k | int dy = y1 - y0; |
175 | 451k | int adx = x1 - x0; |
176 | 451k | int ady = FFABS(dy); |
177 | 451k | int sy = dy < 0 ? -1 : 1; |
178 | 451k | buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; |
179 | 451k | if (ady*2 <= adx) { // optimized common case |
180 | 72.4k | render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); |
181 | 379k | } else { |
182 | 379k | int base = dy / adx; |
183 | 379k | int x = x0; |
184 | 379k | int y = y0; |
185 | 379k | int err = -adx; |
186 | 379k | ady -= FFABS(base) * adx; |
187 | 1.47M | while (++x < x1) { |
188 | 1.09M | y += base; |
189 | 1.09M | err += ady; |
190 | 1.09M | if (err >= 0) { |
191 | 570k | err -= adx; |
192 | 570k | y += sy; |
193 | 570k | } |
194 | 1.09M | buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; |
195 | 1.09M | } |
196 | 379k | } |
197 | 451k | } |
198 | | |
199 | | void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, |
200 | | uint16_t *y_list, int *flag, |
201 | | int multiplier, float *out, int samples) |
202 | 451k | { |
203 | 451k | int lx, ly, i; |
204 | 451k | lx = 0; |
205 | 451k | ly = y_list[0] * multiplier; |
206 | 451k | for (i = 1; i < values; i++) { |
207 | 451k | int pos = list[i].sort; |
208 | 451k | if (flag[pos]) { |
209 | 451k | int x1 = list[pos].x; |
210 | 451k | int y1 = y_list[pos] * multiplier; |
211 | 451k | if (lx < samples) |
212 | 451k | render_line(lx, ly, FFMIN(x1,samples), y1, out); |
213 | 451k | lx = x1; |
214 | 451k | ly = y1; |
215 | 451k | } |
216 | 451k | if (lx >= samples) |
217 | 451k | break; |
218 | 451k | } |
219 | 451k | if (lx < samples) |
220 | 0 | render_line(lx, ly, samples, ly, out); |
221 | 451k | } |