Mercurial > libavcodec.hg
annotate dct.c @ 11557:53822d92c3f7 libavcodec
Make sure the EC code does not attempt to use inter based concealment if there
is no reference frame available. (this can happen because the EC code will attempt
to use reference frames even for I/IDR frames)
author | michael |
---|---|
date | Tue, 30 Mar 2010 20:46:46 +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 } |