Mercurial > libavcodec.hg
annotate dct.c @ 11560:8a4984c5cacc libavcodec
Define AVMediaType enum, and use it instead of enum CodecType, which
is deprecated and will be dropped at the next major bump.
author | stefano |
---|---|
date | Tue, 30 Mar 2010 23:30:55 +0000 |
parents | f468aac92300 |
children | 7dd2a45249a9 |
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 /** | |
25 * @file libavcodec/dct.c | |
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 |
34 /* sin((M_PI * x / (2*n)) */ | |
35 #define SIN(s,n,x) (s->costab[(n) - (x)]) | |
36 | |
37 /* cos((M_PI * x / (2*n)) */ | |
38 #define COS(s,n,x) (s->costab[x]) | |
39 | |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
40 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
|
41 { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
42 int n = 1 << ctx->nbits; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
43 int i; |
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 data[0] = 0; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
46 for(i = 1; i < n/2; i++) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
47 float tmp1 = data[i ]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
48 float tmp2 = data[n - i]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
49 float s = SIN(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
50 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
51 s *= tmp1 + tmp2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
52 tmp1 = (tmp1 - tmp2) * 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
53 data[i ] = s + tmp1; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
54 data[n - i] = s - tmp1; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
55 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
56 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
57 data[n/2] *= 2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
58 ff_rdft_calc(&ctx->rdft, data); |
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[0] *= 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
61 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
62 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
|
63 data[i + 1] += data[i - 1]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
64 data[i ] = -data[i + 2]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
65 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
66 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
67 data[n-1] = 0; |
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 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
|
71 { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
72 int n = 1 << ctx->nbits; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
73 int i; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
74 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
|
75 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
76 for(i = 0; i < n/2; i++) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
77 float tmp1 = data[i ]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
78 float tmp2 = data[n - i]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
79 float s = SIN(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
80 float c = COS(ctx, n, 2*i); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
81 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
82 c *= tmp1 - tmp2; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
83 s *= tmp1 - tmp2; |
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 next += c; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
86 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
87 tmp1 = (tmp1 + tmp2) * 0.5f; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
88 data[i ] = tmp1 - s; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
89 data[n - i] = tmp1 + s; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
90 } |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
91 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
92 ff_rdft_calc(&ctx->rdft, data); |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
93 data[n] = data[1]; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
94 data[1] = next; |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
95 |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
96 for(i = 3; i <= n; i += 2) |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
97 data[i] = data[i - 2] - data[i]; |
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 |
11519
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
100 static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) |
10944 | 101 { |
102 int n = 1 << ctx->nbits; | |
103 int i; | |
104 | |
11520 | 105 float next = data[n - 1]; |
106 float inv_n = 1.0f / n; | |
10944 | 107 |
11520 | 108 for (i = n - 2; i >= 2; i -= 2) { |
109 float val1 = data[i ]; | |
110 float val2 = data[i - 1] - data[i + 1]; | |
111 float c = COS(ctx, n, i); | |
112 float s = SIN(ctx, n, i); | |
10944 | 113 |
11520 | 114 data[i ] = c * val1 + s * val2; |
115 data[i + 1] = s * val1 - c * val2; | |
116 } | |
10944 | 117 |
11520 | 118 data[1] = 2 * next; |
10944 | 119 |
11520 | 120 ff_rdft_calc(&ctx->rdft, data); |
10944 | 121 |
11520 | 122 for (i = 0; i < n / 2; i++) { |
123 float tmp1 = data[i ] * inv_n; | |
124 float tmp2 = data[n - i - 1] * inv_n; | |
125 float csc = ctx->csc2[i] * (tmp1 - tmp2); | |
10944 | 126 |
11520 | 127 tmp1 += tmp2; |
128 data[i ] = tmp1 + csc; | |
129 data[n - i - 1] = tmp1 - csc; | |
130 } | |
11519
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
131 } |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
132 |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
133 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
|
134 { |
c091ab3b4135
Split DCT-II and DCT-III in different functions, they do not share any code.
vitor
parents:
11518
diff
changeset
|
135 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
|
136 int i; |
11520 | 137 float next; |
138 | |
139 for (i=0; i < n/2; i++) { | |
140 float tmp1 = data[i ]; | |
141 float tmp2 = data[n - i - 1]; | |
142 float s = SIN(ctx, n, 2*i + 1); | |
10944 | 143 |
11520 | 144 s *= tmp1 - tmp2; |
145 tmp1 = (tmp1 + tmp2) * 0.5f; | |
10944 | 146 |
11520 | 147 data[i ] = tmp1 + s; |
148 data[n-i-1] = tmp1 - s; | |
149 } | |
10944 | 150 |
11520 | 151 ff_rdft_calc(&ctx->rdft, data); |
10944 | 152 |
11520 | 153 next = data[1] * 0.5; |
154 data[1] *= -1; | |
10944 | 155 |
11520 | 156 for (i = n - 2; i >= 0; i -= 2) { |
157 float inr = data[i ]; | |
158 float ini = data[i + 1]; | |
159 float c = COS(ctx, n, i); | |
160 float s = SIN(ctx, n, i); | |
10944 | 161 |
11520 | 162 data[i ] = c * inr + s * ini; |
10944 | 163 |
11520 | 164 data[i+1] = next; |
10944 | 165 |
11520 | 166 next += s * inr - c * ini; |
167 } | |
10944 | 168 } |
169 | |
170 void ff_dct_calc(DCTContext *s, FFTSample *data) | |
171 { | |
11518
c4d18d452f82
Call DCT by function pointer. Needed for any future ASM implementation and
vitor
parents:
11517
diff
changeset
|
172 s->dct_calc(s, data); |
10944 | 173 } |
174 | |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
175 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
|
176 { |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
177 int n = 1 << nbits; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
178 int i; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
179 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
180 s->nbits = nbits; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
181 s->inverse = inverse; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
182 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
183 ff_init_ff_cos_tabs(nbits+2); |
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 s->costab = ff_cos_tabs[nbits+2]; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
186 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
187 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
|
188 |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
189 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
|
190 av_free(s->csc2); |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
191 return -1; |
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 |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
194 for (i = 0; i < n/2; i++) |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
195 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
|
196 |
11535
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
197 switch(inverse) { |
f468aac92300
Implement the discrete sine/cosine transforms DCT-I and DST-I
vitor
parents:
11520
diff
changeset
|
198 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
|
199 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
|
200 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
|
201 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
|
202 } |
11517
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
203 return 0; |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
204 } |
e3b680f6c106
Cosmetics: move ff_dct_init() to the bottom of the file
vitor
parents:
11370
diff
changeset
|
205 |
10944 | 206 av_cold void ff_dct_end(DCTContext *s) |
207 { | |
208 ff_rdft_end(&s->rdft); | |
209 av_free(s->csc2); | |
210 } |