Mercurial > libavcodec.hg
annotate dct.c @ 12043:f9a0bd0888a4 libavcodec
mpegaudio: call ff_mpegaudiodec_init_mmx() only from float decoder
The mmx code is floating-point only, and this function does not know
from which decoder it is called. Without this change, the integer
decoder only "works" because the size of the context struct is smaller
in this case, and the mmx init function writes the function pointer
outside the allocated context.
author | mru |
---|---|
date | Thu, 01 Jul 2010 23:21:17 +0000 |
parents | 3f3d08bb5cf8 |
children | 1bf322283429 |
rev | line source |
---|---|
10944 | 1 /* |
2 * (I)DCT Transforms | |
3 * Copyright (c) 2009 Peter Ross <pross@xvid.org> | |
4 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> | |
5 * Copyright (c) 2010 Vitor Sessak | |
6 * | |
7 * This file is part of FFmpeg. | |
8 * | |
9 * FFmpeg is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
14 * FFmpeg is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with FFmpeg; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
22 */ | |
23 | |
24 /** | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11535
diff
changeset
|
25 * @file |
10944 | 26 * (Inverse) Discrete Cosine Transforms. These are also known as the |
27 * type II and type III DCTs respectively. | |
28 */ | |
29 | |
30 #include <math.h> | |
11370 | 31 #include "libavutil/mathematics.h" |
32 #include "fft.h" | |
10944 | 33 |
12026
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
34 #define DCT32_FLOAT |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
35 #include "dct32.c" |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
36 |
10944 | 37 /* sin((M_PI * x / (2*n)) */ |
38 #define SIN(s,n,x) (s->costab[(n) - (x)]) | |
39 | |
40 /* cos((M_PI * x / (2*n)) */ | |
41 #define COS(s,n,x) (s->costab[x]) | |
42 | |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
43 static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data) |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
44 { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
45 int n = 1 << ctx->nbits; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
46 int i; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
47 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
48 data[0] = 0; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
49 for(i = 1; i < n/2; i++) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
50 float tmp1 = data[i ]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
51 float tmp2 = data[n - i]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
52 float s = SIN(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
53 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
54 s *= tmp1 + tmp2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
55 tmp1 = (tmp1 - tmp2) * 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
56 data[i ] = s + tmp1; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
57 data[n - i] = s - tmp1; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
58 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
59 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
60 data[n/2] *= 2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
61 ff_rdft_calc(&ctx->rdft, data); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
62 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
63 data[0] *= 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
64 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
65 for(i = 1; i < n-2; i += 2) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
66 data[i + 1] += data[i - 1]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
67 data[i ] = -data[i + 2]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
68 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
69 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
70 data[n-1] = 0; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
71 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
72 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
73 static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data) |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
74 { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
75 int n = 1 << ctx->nbits; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
76 int i; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
77 float next = -0.5f * (data[0] - data[n]); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
78 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
79 for(i = 0; i < n/2; i++) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
80 float tmp1 = data[i ]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
81 float tmp2 = data[n - i]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
82 float s = SIN(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
83 float c = COS(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
84 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
85 c *= tmp1 - tmp2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
86 s *= tmp1 - tmp2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
87 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
88 next += c; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
89 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
90 tmp1 = (tmp1 + tmp2) * 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
91 data[i ] = tmp1 - s; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
92 data[n - i] = tmp1 + s; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
93 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
94 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
95 ff_rdft_calc(&ctx->rdft, data); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
96 data[n] = data[1]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
97 data[1] = next; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
98 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
99 for(i = 3; i <= n; i += 2) |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
100 data[i] = data[i - 2] - data[i]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
101 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
102 |
11519
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
103 static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) |
10944 | 104 { |
105 int n = 1 << ctx->nbits; | |
106 int i; | |
107 | |
11520 | 108 float next = data[n - 1]; |
109 float inv_n = 1.0f / n; | |
10944 | 110 |
11520 | 111 for (i = n - 2; i >= 2; i -= 2) { |
112 float val1 = data[i ]; | |
113 float val2 = data[i - 1] - data[i + 1]; | |
114 float c = COS(ctx, n, i); | |
115 float s = SIN(ctx, n, i); | |
10944 | 116 |
11520 | 117 data[i ] = c * val1 + s * val2; |
118 data[i + 1] = s * val1 - c * val2; | |
119 } | |
10944 | 120 |
11520 | 121 data[1] = 2 * next; |
10944 | 122 |
11520 | 123 ff_rdft_calc(&ctx->rdft, data); |
10944 | 124 |
11520 | 125 for (i = 0; i < n / 2; i++) { |
126 float tmp1 = data[i ] * inv_n; | |
127 float tmp2 = data[n - i - 1] * inv_n; | |
128 float csc = ctx->csc2[i] * (tmp1 - tmp2); | |
10944 | 129 |
11520 | 130 tmp1 += tmp2; |
131 data[i ] = tmp1 + csc; | |
132 data[n - i - 1] = tmp1 - csc; | |
133 } | |
11519
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
134 } |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
135 |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
136 static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data) |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
137 { |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
138 int n = 1 << ctx->nbits; |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
139 int i; |
11520 | 140 float next; |
141 | |
142 for (i=0; i < n/2; i++) { | |
143 float tmp1 = data[i ]; | |
144 float tmp2 = data[n - i - 1]; | |
145 float s = SIN(ctx, n, 2*i + 1); | |
10944 | 146 |
11520 | 147 s *= tmp1 - tmp2; |
148 tmp1 = (tmp1 + tmp2) * 0.5f; | |
10944 | 149 |
11520 | 150 data[i ] = tmp1 + s; |
151 data[n-i-1] = tmp1 - s; | |
152 } | |
10944 | 153 |
11520 | 154 ff_rdft_calc(&ctx->rdft, data); |
10944 | 155 |
11520 | 156 next = data[1] * 0.5; |
157 data[1] *= -1; | |
10944 | 158 |
11520 | 159 for (i = n - 2; i >= 0; i -= 2) { |
160 float inr = data[i ]; | |
161 float ini = data[i + 1]; | |
162 float c = COS(ctx, n, i); | |
163 float s = SIN(ctx, n, i); | |
10944 | 164 |
11520 | 165 data[i ] = c * inr + s * ini; |
10944 | 166 |
11520 | 167 data[i+1] = next; |
10944 | 168 |
11520 | 169 next += s * inr - c * ini; |
170 } | |
10944 | 171 } |
172 | |
12026
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
173 static void dct32_func(DCTContext *ctx, FFTSample *data) |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
174 { |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
175 ctx->dct32(data, data); |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
176 } |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
177 |
10944 | 178 void ff_dct_calc(DCTContext *s, FFTSample *data) |
179 { | |
11518
c4d18d452f82
Call DCT by function pointer. Needed for any future ASM implementation and
vitor
parents:
11517
diff
changeset
|
180 s->dct_calc(s, data); |
10944 | 181 } |
182 | |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
183 av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) |
11517
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
184 { |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
185 int n = 1 << nbits; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
186 int i; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
187 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
188 s->nbits = nbits; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
189 s->inverse = inverse; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
190 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
191 ff_init_ff_cos_tabs(nbits+2); |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
192 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
193 s->costab = ff_cos_tabs[nbits+2]; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
194 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
195 s->csc2 = av_malloc(n/2 * sizeof(FFTSample)); |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
196 |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
197 if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) { |
11517
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
198 av_free(s->csc2); |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
199 return -1; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
200 } |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
201 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
202 for (i = 0; i < n/2; i++) |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
203 s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1))); |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
204 |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
205 switch(inverse) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
206 case DCT_I : s->dct_calc = ff_dct_calc_I_c; break; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
207 case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
208 case DCT_III: s->dct_calc = ff_dct_calc_III_c; break; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
209 case DST_I : s->dct_calc = ff_dst_calc_I_c; break; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
210 } |
12026
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
211 |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
212 if (inverse == DCT_II && nbits == 5) |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
213 s->dct_calc = dct32_func; |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
214 |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
215 s->dct32 = dct32; |
3f3d08bb5cf8
More mp{1,2,3} 32-point DCT transform to our common DCT framework.
vitor
parents:
11644
diff
changeset
|
216 |
11517
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
217 return 0; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
218 } |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
219 |
10944 | 220 av_cold void ff_dct_end(DCTContext *s) |
221 { | |
222 ff_rdft_end(&s->rdft); | |
223 av_free(s->csc2); | |
224 } |