/src/ffmpeg/libavcodec/wmv2dsp.c
Line | Count | Source |
1 | | /* |
2 | | * This file is part of FFmpeg. |
3 | | * |
4 | | * FFmpeg is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * FFmpeg is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with FFmpeg; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #include "config.h" |
20 | | #include "libavutil/attributes.h" |
21 | | #include "libavutil/common.h" |
22 | | #include "idctdsp.h" |
23 | | #include "mathops.h" |
24 | | #include "wmv2dsp.h" |
25 | | |
26 | 1.23G | #define W0 2048 |
27 | 617M | #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ |
28 | 617M | #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ |
29 | 617M | #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ |
30 | | #define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ |
31 | 617M | #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ |
32 | 617M | #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ |
33 | 617M | #define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ |
34 | | |
35 | | static void wmv2_idct_row(short * b) |
36 | 154M | { |
37 | 154M | int s1, s2; |
38 | 154M | int a0, a1, a2, a3, a4, a5, a6, a7; |
39 | | |
40 | | /* step 1 */ |
41 | 154M | a1 = W1 * b[1] + W7 * b[7]; |
42 | 154M | a7 = W7 * b[1] - W1 * b[7]; |
43 | 154M | a5 = W5 * b[5] + W3 * b[3]; |
44 | 154M | a3 = W3 * b[5] - W5 * b[3]; |
45 | 154M | a2 = W2 * b[2] + W6 * b[6]; |
46 | 154M | a6 = W6 * b[2] - W2 * b[6]; |
47 | 154M | a0 = W0 * b[0] + W0 * b[4]; |
48 | 154M | a4 = W0 * b[0] - W0 * b[4]; |
49 | | |
50 | | /* step 2 */ |
51 | 154M | s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7 |
52 | 154M | s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8; |
53 | | |
54 | | /* step 3 */ |
55 | 154M | b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8; |
56 | 154M | b[1] = (a4 + a6 + s1 + (1 << 7)) >> 8; |
57 | 154M | b[2] = (a4 - a6 + s2 + (1 << 7)) >> 8; |
58 | 154M | b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8; |
59 | 154M | b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8; |
60 | 154M | b[5] = (a4 - a6 - s2 + (1 << 7)) >> 8; |
61 | 154M | b[6] = (a4 + a6 - s1 + (1 << 7)) >> 8; |
62 | 154M | b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8; |
63 | 154M | } |
64 | | |
65 | | static void wmv2_idct_col(short * b) |
66 | 154M | { |
67 | 154M | int s1, s2; |
68 | 154M | int a0, a1, a2, a3, a4, a5, a6, a7; |
69 | | |
70 | | /* step 1, with extended precision */ |
71 | 154M | a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3; |
72 | 154M | a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3; |
73 | 154M | a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3; |
74 | 154M | a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3; |
75 | 154M | a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3; |
76 | 154M | a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3; |
77 | 154M | a0 = (W0 * b[8 * 0] + W0 * b[8 * 4] ) >> 3; |
78 | 154M | a4 = (W0 * b[8 * 0] - W0 * b[8 * 4] ) >> 3; |
79 | | |
80 | | /* step 2 */ |
81 | 154M | s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8; |
82 | 154M | s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8; |
83 | | |
84 | | /* step 3 */ |
85 | 154M | b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14; |
86 | 154M | b[8 * 1] = (a4 + a6 + s1 + (1 << 13)) >> 14; |
87 | 154M | b[8 * 2] = (a4 - a6 + s2 + (1 << 13)) >> 14; |
88 | 154M | b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14; |
89 | | |
90 | 154M | b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14; |
91 | 154M | b[8 * 5] = (a4 - a6 - s2 + (1 << 13)) >> 14; |
92 | 154M | b[8 * 6] = (a4 + a6 - s1 + (1 << 13)) >> 14; |
93 | 154M | b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14; |
94 | 154M | } |
95 | | |
96 | | static void wmv2_idct_add_c(uint8_t *dest, ptrdiff_t line_size, int16_t *block) |
97 | 10.1M | { |
98 | 10.1M | int i; |
99 | | |
100 | 91.1M | for (i = 0; i < 64; i += 8) |
101 | 81.0M | wmv2_idct_row(block + i); |
102 | 91.1M | for (i = 0; i < 8; i++) |
103 | 81.0M | wmv2_idct_col(block + i); |
104 | | |
105 | 91.1M | for (i = 0; i < 8; i++) { |
106 | 81.0M | dest[0] = av_clip_uint8(dest[0] + block[0]); |
107 | 81.0M | dest[1] = av_clip_uint8(dest[1] + block[1]); |
108 | 81.0M | dest[2] = av_clip_uint8(dest[2] + block[2]); |
109 | 81.0M | dest[3] = av_clip_uint8(dest[3] + block[3]); |
110 | 81.0M | dest[4] = av_clip_uint8(dest[4] + block[4]); |
111 | 81.0M | dest[5] = av_clip_uint8(dest[5] + block[5]); |
112 | 81.0M | dest[6] = av_clip_uint8(dest[6] + block[6]); |
113 | 81.0M | dest[7] = av_clip_uint8(dest[7] + block[7]); |
114 | 81.0M | dest += line_size; |
115 | 81.0M | block += 8; |
116 | 81.0M | } |
117 | 10.1M | } |
118 | | |
119 | | static void wmv2_idct_put_c(uint8_t *dest, ptrdiff_t line_size, int16_t *block) |
120 | 9.15M | { |
121 | 9.15M | int i; |
122 | | |
123 | 82.4M | for (i = 0; i < 64; i += 8) |
124 | 73.2M | wmv2_idct_row(block + i); |
125 | 82.4M | for (i = 0; i < 8; i++) |
126 | 73.2M | wmv2_idct_col(block + i); |
127 | | |
128 | 82.4M | for (i = 0; i < 8; i++) { |
129 | 73.2M | dest[0] = av_clip_uint8(block[0]); |
130 | 73.2M | dest[1] = av_clip_uint8(block[1]); |
131 | 73.2M | dest[2] = av_clip_uint8(block[2]); |
132 | 73.2M | dest[3] = av_clip_uint8(block[3]); |
133 | 73.2M | dest[4] = av_clip_uint8(block[4]); |
134 | 73.2M | dest[5] = av_clip_uint8(block[5]); |
135 | 73.2M | dest[6] = av_clip_uint8(block[6]); |
136 | 73.2M | dest[7] = av_clip_uint8(block[7]); |
137 | 73.2M | dest += line_size; |
138 | 73.2M | block += 8; |
139 | 73.2M | } |
140 | 9.15M | } |
141 | | |
142 | | av_cold void ff_wmv2dsp_init(IDCTDSPContext *c) |
143 | 65.3k | { |
144 | 65.3k | c->idct_add = wmv2_idct_add_c; |
145 | 65.3k | c->idct_put = wmv2_idct_put_c; |
146 | 65.3k | c->idct = NULL; |
147 | 65.3k | c->perm_type = FF_IDCT_PERM_NONE; |
148 | | |
149 | | #if ARCH_MIPS |
150 | | ff_wmv2dsp_init_mips(c); |
151 | | #endif |
152 | 65.3k | ff_init_scantable_permutation(c->idct_permutation, |
153 | 65.3k | c->perm_type); |
154 | 65.3k | } |