blob: a3ca07b518f3881741524bfa0a4a590f89d8a00d
1 | /* |
2 | * Copyright (c) 2000, 2001 Fabrice Bellard |
3 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with FFmpeg; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | |
23 | #include <stddef.h> |
24 | |
25 | #include "libavutil/avassert.h" |
26 | #include "bit_depth_template.c" |
27 | |
28 | #define H264_CHROMA_MC(OPNAME, OP)\ |
29 | static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y){\ |
30 | pixel *dst = (pixel*)_dst;\ |
31 | pixel *src = (pixel*)_src;\ |
32 | const int A=(8-x)*(8-y);\ |
33 | const int B=( x)*(8-y);\ |
34 | const int C=(8-x)*( y);\ |
35 | const int D=( x)*( y);\ |
36 | int i;\ |
37 | stride >>= sizeof(pixel)-1;\ |
38 | \ |
39 | av_assert2(x<8 && y<8 && x>=0 && y>=0);\ |
40 | \ |
41 | if(D){\ |
42 | for(i=0; i<h; i++){\ |
43 | OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ |
44 | dst+= stride;\ |
45 | src+= stride;\ |
46 | }\ |
47 | } else if (B + C) {\ |
48 | const int E= B+C;\ |
49 | const int step= C ? stride : 1;\ |
50 | for(i=0; i<h; i++){\ |
51 | OP(dst[0], (A*src[0] + E*src[step+0]));\ |
52 | dst+= stride;\ |
53 | src+= stride;\ |
54 | }\ |
55 | } else {\ |
56 | for(i=0; i<h; i++){\ |
57 | OP(dst[0], (A*src[0]));\ |
58 | dst+= stride;\ |
59 | src+= stride;\ |
60 | }\ |
61 | }\ |
62 | }\ |
63 | static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ |
64 | {\ |
65 | pixel *dst = (pixel*)_dst;\ |
66 | pixel *src = (pixel*)_src;\ |
67 | const int A=(8-x)*(8-y);\ |
68 | const int B=( x)*(8-y);\ |
69 | const int C=(8-x)*( y);\ |
70 | const int D=( x)*( y);\ |
71 | int i;\ |
72 | stride >>= sizeof(pixel)-1;\ |
73 | \ |
74 | av_assert2(x<8 && y<8 && x>=0 && y>=0);\ |
75 | \ |
76 | if(D){\ |
77 | for(i=0; i<h; i++){\ |
78 | OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ |
79 | OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ |
80 | dst+= stride;\ |
81 | src+= stride;\ |
82 | }\ |
83 | } else if (B + C) {\ |
84 | const int E= B+C;\ |
85 | const ptrdiff_t step = C ? stride : 1;\ |
86 | for(i=0; i<h; i++){\ |
87 | OP(dst[0], (A*src[0] + E*src[step+0]));\ |
88 | OP(dst[1], (A*src[1] + E*src[step+1]));\ |
89 | dst+= stride;\ |
90 | src+= stride;\ |
91 | }\ |
92 | } else {\ |
93 | for ( i = 0; i < h; i++){\ |
94 | OP(dst[0], A * src[0]);\ |
95 | OP(dst[1], A * src[1]);\ |
96 | dst += stride;\ |
97 | src += stride;\ |
98 | }\ |
99 | }\ |
100 | }\ |
101 | \ |
102 | static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ |
103 | {\ |
104 | pixel *dst = (pixel*)_dst;\ |
105 | pixel *src = (pixel*)_src;\ |
106 | const int A=(8-x)*(8-y);\ |
107 | const int B=( x)*(8-y);\ |
108 | const int C=(8-x)*( y);\ |
109 | const int D=( x)*( y);\ |
110 | int i;\ |
111 | stride >>= sizeof(pixel)-1;\ |
112 | \ |
113 | av_assert2(x<8 && y<8 && x>=0 && y>=0);\ |
114 | \ |
115 | if(D){\ |
116 | for(i=0; i<h; i++){\ |
117 | OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ |
118 | OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ |
119 | OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ |
120 | OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ |
121 | dst+= stride;\ |
122 | src+= stride;\ |
123 | }\ |
124 | } else if (B + C) {\ |
125 | const int E= B+C;\ |
126 | const ptrdiff_t step = C ? stride : 1;\ |
127 | for(i=0; i<h; i++){\ |
128 | OP(dst[0], (A*src[0] + E*src[step+0]));\ |
129 | OP(dst[1], (A*src[1] + E*src[step+1]));\ |
130 | OP(dst[2], (A*src[2] + E*src[step+2]));\ |
131 | OP(dst[3], (A*src[3] + E*src[step+3]));\ |
132 | dst+= stride;\ |
133 | src+= stride;\ |
134 | }\ |
135 | } else {\ |
136 | for ( i = 0; i < h; i++){\ |
137 | OP(dst[0], A * src[0]);\ |
138 | OP(dst[1], A * src[1]);\ |
139 | OP(dst[2], A * src[2]);\ |
140 | OP(dst[3], A * src[3]);\ |
141 | dst += stride;\ |
142 | src += stride;\ |
143 | }\ |
144 | }\ |
145 | }\ |
146 | \ |
147 | static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ |
148 | {\ |
149 | pixel *dst = (pixel*)_dst;\ |
150 | pixel *src = (pixel*)_src;\ |
151 | const int A=(8-x)*(8-y);\ |
152 | const int B=( x)*(8-y);\ |
153 | const int C=(8-x)*( y);\ |
154 | const int D=( x)*( y);\ |
155 | int i;\ |
156 | stride >>= sizeof(pixel)-1;\ |
157 | \ |
158 | av_assert2(x<8 && y<8 && x>=0 && y>=0);\ |
159 | \ |
160 | if(D){\ |
161 | for(i=0; i<h; i++){\ |
162 | OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ |
163 | OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ |
164 | OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ |
165 | OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ |
166 | OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\ |
167 | OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\ |
168 | OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\ |
169 | OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\ |
170 | dst+= stride;\ |
171 | src+= stride;\ |
172 | }\ |
173 | } else if (B + C) {\ |
174 | const int E= B+C;\ |
175 | const ptrdiff_t step = C ? stride : 1;\ |
176 | for(i=0; i<h; i++){\ |
177 | OP(dst[0], (A*src[0] + E*src[step+0]));\ |
178 | OP(dst[1], (A*src[1] + E*src[step+1]));\ |
179 | OP(dst[2], (A*src[2] + E*src[step+2]));\ |
180 | OP(dst[3], (A*src[3] + E*src[step+3]));\ |
181 | OP(dst[4], (A*src[4] + E*src[step+4]));\ |
182 | OP(dst[5], (A*src[5] + E*src[step+5]));\ |
183 | OP(dst[6], (A*src[6] + E*src[step+6]));\ |
184 | OP(dst[7], (A*src[7] + E*src[step+7]));\ |
185 | dst+= stride;\ |
186 | src+= stride;\ |
187 | }\ |
188 | } else {\ |
189 | for ( i = 0; i < h; i++){\ |
190 | OP(dst[0], A * src[0]);\ |
191 | OP(dst[1], A * src[1]);\ |
192 | OP(dst[2], A * src[2]);\ |
193 | OP(dst[3], A * src[3]);\ |
194 | OP(dst[4], A * src[4]);\ |
195 | OP(dst[5], A * src[5]);\ |
196 | OP(dst[6], A * src[6]);\ |
197 | OP(dst[7], A * src[7]);\ |
198 | dst += stride;\ |
199 | src += stride;\ |
200 | }\ |
201 | }\ |
202 | } |
203 | |
204 | #define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1) |
205 | #define op_put(a, b) a = (((b) + 32)>>6) |
206 | |
207 | H264_CHROMA_MC(put_ , op_put) |
208 | H264_CHROMA_MC(avg_ , op_avg) |
209 | #undef op_avg |
210 | #undef op_put |
211 |