annotate dct.c @ 11225:5811a86f55f1 libavcodec

Use memset to set the runs partially coded superblocks Much faster for long runs (e.g. nearly uncoded frames), slightly faster for the general case.
author conrad
date Sun, 21 Feb 2010 00:10:47 +0000
parents 0985f1f7ab72
children 4b3da727d832
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10944
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
1 /*
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
2 * (I)DCT Transforms
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
3 * Copyright (c) 2009 Peter Ross <pross@xvid.org>
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
4 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
5 * Copyright (c) 2010 Vitor Sessak
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
6 *
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
7 * This file is part of FFmpeg.
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
8 *
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
13 *
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
17 * Lesser General Public License for more details.
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
18 *
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
22 */
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
23
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
24 /**
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
25 * @file libavcodec/dct.c
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
26 * (Inverse) Discrete Cosine Transforms. These are also known as the
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
27 * type II and type III DCTs respectively.
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
28 */
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
29
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
30 #include <math.h>
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
31 #include "dsputil.h"
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
32
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
33 av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
34 {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
35 int n = 1 << nbits;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
36 int i;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
37
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
38 s->nbits = nbits;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
39 s->inverse = inverse;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
40
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
41 ff_init_ff_cos_tabs(nbits+2);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
42
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
43 s->costab = ff_cos_tabs[nbits+2];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
44
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
45 s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
46
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
47 if (ff_rdft_init(&s->rdft, nbits, inverse) < 0) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
48 av_free(s->csc2);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
49 return -1;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
50 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
51
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
52 for (i = 0; i < n/2; i++)
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
53 s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
54
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
55 return 0;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
56 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
57
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
58 /* sin((M_PI * x / (2*n)) */
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
59 #define SIN(s,n,x) (s->costab[(n) - (x)])
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
60
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
61 /* cos((M_PI * x / (2*n)) */
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
62 #define COS(s,n,x) (s->costab[x])
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
63
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
64 static void ff_dct_calc_c(DCTContext *ctx, FFTSample *data)
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
65 {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
66 int n = 1 << ctx->nbits;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
67 int i;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
68
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
69 if (ctx->inverse) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
70 float next = data[n - 1];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
71 float inv_n = 1.0f / n;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
72
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
73 for (i = n - 2; i >= 2; i -= 2) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
74 float val1 = data[i ];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
75 float val2 = data[i - 1] - data[i + 1];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
76 float c = COS(ctx, n, i);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
77 float s = SIN(ctx, n, i);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
78
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
79 data[i ] = c * val1 + s * val2;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
80 data[i + 1] = s * val1 - c * val2;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
81 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
82
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
83 data[1] = 2 * next;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
84
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
85 ff_rdft_calc(&ctx->rdft, data);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
86
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
87 for (i = 0; i < n / 2; i++) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
88 float tmp1 = data[i ] * inv_n;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
89 float tmp2 = data[n - i - 1] * inv_n;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
90 float csc = ctx->csc2[i] * (tmp1 - tmp2);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
91
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
92 tmp1 += tmp2;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
93 data[i ] = tmp1 + csc;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
94 data[n - i - 1] = tmp1 - csc;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
95 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
96 } else {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
97 float next;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
98 for (i=0; i < n/2; i++) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
99 float tmp1 = data[i ];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
100 float tmp2 = data[n - i - 1];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
101 float s = SIN(ctx, n, 2*i + 1);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
102
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
103 s *= tmp1 - tmp2;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
104 tmp1 = (tmp1 + tmp2) * 0.5f;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
105
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
106 data[i ] = tmp1 + s;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
107 data[n-i-1] = tmp1 - s;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
108 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
109
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
110 ff_rdft_calc(&ctx->rdft, data);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
111
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
112 next = data[1] * 0.5;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
113 data[1] *= -1;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
114
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
115 for (i = n - 2; i >= 0; i -= 2) {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
116 float inr = data[i ];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
117 float ini = data[i + 1];
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
118 float c = COS(ctx, n, i);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
119 float s = SIN(ctx, n, i);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
120
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
121 data[i ] = c * inr + s * ini;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
122
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
123 data[i+1] = next;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
124
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
125 next += s * inr - c * ini;
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
126 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
127 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
128 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
129
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
130 void ff_dct_calc(DCTContext *s, FFTSample *data)
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
131 {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
132 ff_dct_calc_c(s, data);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
133 }
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
134
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
135 av_cold void ff_dct_end(DCTContext *s)
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
136 {
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
137 ff_rdft_end(&s->rdft);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
138 av_free(s->csc2);
0985f1f7ab72 Floating point discrete cosine transform
vitor
parents:
diff changeset
139 }