ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/trunk/xvidcore/src/image/qpel.h
Revision: 1382
Committed: Mon Mar 22 22:36:25 2004 UTC (20 years, 6 months ago) by edgomez
Content type: text/plain
File size: 11057 byte(s)
Error occurred while calculating annotation data.
Log Message:
xvidcore 1.0.0 rc3 merge back to HEAD

File Contents

# Content
1 /*****************************************************************************
2 *
3 * XVID MPEG-4 VIDEO CODEC
4 * - QPel interpolation -
5 *
6 * Copyright(C) 2003 Pascal Massimino <skal@planet-d.net>
7 *
8 * This program is free software ; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation ; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program ; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * $Id: qpel.h,v 1.2 2004-03-22 22:36:23 edgomez Exp $
23 *
24 ****************************************************************************/
25
26 #ifndef _XVID_QPEL_H_
27 #define _XVID_QPEL_H_
28
29 #include "../utils/mem_transfer.h"
30
31 /*****************************************************************************
32 * Signatures
33 ****************************************************************************/
34
35 #define XVID_QP_PASS_SIGNATURE(NAME) \
36 void (NAME)(uint8_t *dst, const uint8_t *src, int32_t length, int32_t BpS, int32_t rounding)
37
38 typedef XVID_QP_PASS_SIGNATURE(XVID_QP_PASS);
39
40 /* We put everything in a single struct so it can easily be passed
41 * to prediction functions as a whole... */
42
43 typedef struct _XVID_QP_FUNCS {
44
45 /* filter for QPel 16x? prediction */
46
47 XVID_QP_PASS *H_Pass;
48 XVID_QP_PASS *H_Pass_Avrg;
49 XVID_QP_PASS *H_Pass_Avrg_Up;
50 XVID_QP_PASS *V_Pass;
51 XVID_QP_PASS *V_Pass_Avrg;
52 XVID_QP_PASS *V_Pass_Avrg_Up;
53
54 /* filter for QPel 8x? prediction */
55
56 XVID_QP_PASS *H_Pass_8;
57 XVID_QP_PASS *H_Pass_Avrg_8;
58 XVID_QP_PASS *H_Pass_Avrg_Up_8;
59 XVID_QP_PASS *V_Pass_8;
60 XVID_QP_PASS *V_Pass_Avrg_8;
61 XVID_QP_PASS *V_Pass_Avrg_Up_8;
62 } XVID_QP_FUNCS;
63
64 /*****************************************************************************
65 * fwd dcl
66 ****************************************************************************/
67 extern void xvid_Init_QP();
68
69 extern XVID_QP_FUNCS xvid_QP_Funcs_C; /* for P-frames */
70 extern XVID_QP_FUNCS xvid_QP_Add_Funcs_C; /* for B-frames */
71
72 #ifdef ARCH_IS_IA32
73 extern XVID_QP_FUNCS xvid_QP_Funcs_mmx;
74 extern XVID_QP_FUNCS xvid_QP_Add_Funcs_mmx;
75 #endif
76
77 extern XVID_QP_FUNCS *xvid_QP_Funcs; /* <- main pointer for enc/dec structure */
78 extern XVID_QP_FUNCS *xvid_QP_Add_Funcs; /* <- main pointer for enc/dec structure */
79
80 /*****************************************************************************
81 * macros
82 ****************************************************************************/
83
84 /*****************************************************************************
85
86 Passes to be performed
87
88 case 0: copy
89 case 2: h-pass
90 case 1/3: h-pass + h-avrg
91 case 8: v-pass
92 case 10: h-pass + v-pass
93 case 9/11: h-pass + h-avrg + v-pass
94 case 4/12: v-pass + v-avrg
95 case 6/14: h-pass + v-pass + v-avrg
96 case 5/13/7/15: h-pass + h-avrg + v-pass + v-avrg
97
98 ****************************************************************************/
99
100 static void __inline
101 new_interpolate16x16_quarterpel(uint8_t * const cur,
102 uint8_t * const refn,
103 uint8_t * const refh,
104 uint8_t * const refv,
105 uint8_t * const refhv,
106 const uint32_t x, const uint32_t y,
107 const int32_t dx, const int dy,
108 const uint32_t stride,
109 const uint32_t rounding)
110 {
111 const uint8_t *src;
112 uint8_t *dst;
113 uint8_t *tmp;
114 int32_t quads;
115 const XVID_QP_FUNCS *Ops;
116
117 int32_t x_int, y_int;
118
119 const int32_t xRef = x*4 + dx;
120 const int32_t yRef = y*4 + dy;
121
122 Ops = xvid_QP_Funcs; /* TODO: pass as argument */
123 quads = (dx&3) | ((dy&3)<<2);
124
125 x_int = xRef/4;
126 if (xRef < 0 && xRef % 4)
127 x_int--;
128
129 y_int = yRef/4;
130 if (yRef < 0 && yRef % 4)
131 y_int--;
132
133 dst = cur + y * stride + x;
134 src = refn + y_int * stride + x_int;
135
136 tmp = refh; /* we need at least a 16 x stride scratch block */
137
138 switch(quads) {
139 case 0:
140 transfer8x8_copy( dst, src, stride);
141 transfer8x8_copy( dst+8, src+8, stride);
142 transfer8x8_copy( dst+8*stride, src+8*stride, stride);
143 transfer8x8_copy( dst+8*stride+8, src+8*stride+8, stride);
144 break;
145 case 1:
146 Ops->H_Pass_Avrg(dst, src, 16, stride, rounding);
147 break;
148 case 2:
149 Ops->H_Pass(dst, src, 16, stride, rounding);
150 break;
151 case 3:
152 Ops->H_Pass_Avrg_Up(dst, src, 16, stride, rounding);
153 break;
154 case 4:
155 Ops->V_Pass_Avrg(dst, src, 16, stride, rounding);
156 break;
157 case 5:
158 Ops->H_Pass_Avrg(tmp, src, 17, stride, rounding);
159 Ops->V_Pass_Avrg(dst, tmp, 16, stride, rounding);
160 break;
161 case 6:
162 Ops->H_Pass(tmp, src, 17, stride, rounding);
163 Ops->V_Pass_Avrg(dst, tmp, 16, stride, rounding);
164 break;
165 case 7:
166 Ops->H_Pass_Avrg_Up(tmp, src, 17, stride, rounding);
167 Ops->V_Pass_Avrg(dst, tmp, 16, stride, rounding);
168 break;
169 case 8:
170 Ops->V_Pass(dst, src, 16, stride, rounding);
171 break;
172 case 9:
173 Ops->H_Pass_Avrg(tmp, src, 17, stride, rounding);
174 Ops->V_Pass(dst, tmp, 16, stride, rounding);
175 break;
176 case 10:
177 Ops->H_Pass(tmp, src, 17, stride, rounding);
178 Ops->V_Pass(dst, tmp, 16, stride, rounding);
179 break;
180 case 11:
181 Ops->H_Pass_Avrg_Up(tmp, src, 17, stride, rounding);
182 Ops->V_Pass(dst, tmp, 16, stride, rounding);
183 break;
184 case 12:
185 Ops->V_Pass_Avrg_Up(dst, src, 16, stride, rounding);
186 break;
187 case 13:
188 Ops->H_Pass_Avrg(tmp, src, 17, stride, rounding);
189 Ops->V_Pass_Avrg_Up(dst, tmp, 16, stride, rounding);
190 break;
191 case 14:
192 Ops->H_Pass(tmp, src, 17, stride, rounding);
193 Ops->V_Pass_Avrg_Up( dst, tmp, 16, stride, rounding);
194 break;
195 case 15:
196 Ops->H_Pass_Avrg_Up(tmp, src, 17, stride, rounding);
197 Ops->V_Pass_Avrg_Up(dst, tmp, 16, stride, rounding);
198 break;
199 }
200 }
201
202 static void __inline
203 new_interpolate16x8_quarterpel(uint8_t * const cur,
204 uint8_t * const refn,
205 uint8_t * const refh,
206 uint8_t * const refv,
207 uint8_t * const refhv,
208 const uint32_t x, const uint32_t y,
209 const int32_t dx, const int dy,
210 const uint32_t stride,
211 const uint32_t rounding)
212 {
213 const uint8_t *src;
214 uint8_t *dst;
215 uint8_t *tmp;
216 int32_t quads;
217 const XVID_QP_FUNCS *Ops;
218
219 int32_t x_int, y_int;
220
221 const int32_t xRef = x*4 + dx;
222 const int32_t yRef = y*4 + dy;
223
224 Ops = xvid_QP_Funcs; /* TODO: pass as argument */
225 quads = (dx&3) | ((dy&3)<<2);
226
227 x_int = xRef/4;
228 if (xRef < 0 && xRef % 4)
229 x_int--;
230
231 y_int = yRef/4;
232 if (yRef < 0 && yRef % 4)
233 y_int--;
234
235 dst = cur + y * stride + x;
236 src = refn + y_int * stride + x_int;
237
238 tmp = refh; /* we need at least a 16 x stride scratch block */
239
240 switch(quads) {
241 case 0:
242 transfer8x8_copy( dst, src, stride);
243 transfer8x8_copy( dst+8, src+8, stride);
244 break;
245 case 1:
246 Ops->H_Pass_Avrg(dst, src, 8, stride, rounding);
247 break;
248 case 2:
249 Ops->H_Pass(dst, src, 8, stride, rounding);
250 break;
251 case 3:
252 Ops->H_Pass_Avrg_Up(dst, src, 8, stride, rounding);
253 break;
254 case 4:
255 Ops->V_Pass_Avrg_8(dst, src, 16, stride, rounding);
256 break;
257 case 5:
258 Ops->H_Pass_Avrg(tmp, src, 9, stride, rounding);
259 Ops->V_Pass_Avrg_8(dst, tmp, 16, stride, rounding);
260 break;
261 case 6:
262 Ops->H_Pass(tmp, src, 9, stride, rounding);
263 Ops->V_Pass_Avrg_8(dst, tmp, 16, stride, rounding);
264 break;
265 case 7:
266 Ops->H_Pass_Avrg_Up(tmp, src, 9, stride, rounding);
267 Ops->V_Pass_Avrg_8(dst, tmp, 16, stride, rounding);
268 break;
269 case 8:
270 Ops->V_Pass_8(dst, src, 16, stride, rounding);
271 break;
272 case 9:
273 Ops->H_Pass_Avrg(tmp, src, 9, stride, rounding);
274 Ops->V_Pass_8(dst, tmp, 16, stride, rounding);
275 break;
276 case 10:
277 Ops->H_Pass(tmp, src, 9, stride, rounding);
278 Ops->V_Pass_8(dst, tmp, 16, stride, rounding);
279 break;
280 case 11:
281 Ops->H_Pass_Avrg_Up(tmp, src, 9, stride, rounding);
282 Ops->V_Pass_8(dst, tmp, 16, stride, rounding);
283 break;
284 case 12:
285 Ops->V_Pass_Avrg_Up_8(dst, src, 16, stride, rounding);
286 break;
287 case 13:
288 Ops->H_Pass_Avrg(tmp, src, 9, stride, rounding);
289 Ops->V_Pass_Avrg_Up_8(dst, tmp, 16, stride, rounding);
290 break;
291 case 14:
292 Ops->H_Pass(tmp, src, 9, stride, rounding);
293 Ops->V_Pass_Avrg_Up_8( dst, tmp, 16, stride, rounding);
294 break;
295 case 15:
296 Ops->H_Pass_Avrg_Up(tmp, src, 9, stride, rounding);
297 Ops->V_Pass_Avrg_Up_8(dst, tmp, 16, stride, rounding);
298 break;
299 }
300 }
301
302 static void __inline
303 new_interpolate8x8_quarterpel(uint8_t * const cur,
304 uint8_t * const refn,
305 uint8_t * const refh,
306 uint8_t * const refv,
307 uint8_t * const refhv,
308 const uint32_t x, const uint32_t y,
309 const int32_t dx, const int dy,
310 const uint32_t stride,
311 const uint32_t rounding)
312 {
313 const uint8_t *src;
314 uint8_t *dst;
315 uint8_t *tmp;
316 int32_t quads;
317 const XVID_QP_FUNCS *Ops;
318
319 int32_t x_int, y_int;
320
321 const int32_t xRef = x*4 + dx;
322 const int32_t yRef = y*4 + dy;
323
324 Ops = xvid_QP_Funcs; /* TODO: pass as argument */
325 quads = (dx&3) | ((dy&3)<<2);
326
327 x_int = xRef/4;
328 if (xRef < 0 && xRef % 4)
329 x_int--;
330
331 y_int = yRef/4;
332 if (yRef < 0 && yRef % 4)
333 y_int--;
334
335 dst = cur + y * stride + x;
336 src = refn + y_int * stride + x_int;
337
338 tmp = refh; /* we need at least a 16 x stride scratch block */
339
340 switch(quads) {
341 case 0:
342 transfer8x8_copy( dst, src, stride);
343 break;
344 case 1:
345 Ops->H_Pass_Avrg_8(dst, src, 8, stride, rounding);
346 break;
347 case 2:
348 Ops->H_Pass_8(dst, src, 8, stride, rounding);
349 break;
350 case 3:
351 Ops->H_Pass_Avrg_Up_8(dst, src, 8, stride, rounding);
352 break;
353 case 4:
354 Ops->V_Pass_Avrg_8(dst, src, 8, stride, rounding);
355 break;
356 case 5:
357 Ops->H_Pass_Avrg_8(tmp, src, 9, stride, rounding);
358 Ops->V_Pass_Avrg_8(dst, tmp, 8, stride, rounding);
359 break;
360 case 6:
361 Ops->H_Pass_8(tmp, src, 9, stride, rounding);
362 Ops->V_Pass_Avrg_8(dst, tmp, 8, stride, rounding);
363 break;
364 case 7:
365 Ops->H_Pass_Avrg_Up_8(tmp, src, 9, stride, rounding);
366 Ops->V_Pass_Avrg_8(dst, tmp, 8, stride, rounding);
367 break;
368 case 8:
369 Ops->V_Pass_8(dst, src, 8, stride, rounding);
370 break;
371 case 9:
372 Ops->H_Pass_Avrg_8(tmp, src, 9, stride, rounding);
373 Ops->V_Pass_8(dst, tmp, 8, stride, rounding);
374 break;
375 case 10:
376 Ops->H_Pass_8(tmp, src, 9, stride, rounding);
377 Ops->V_Pass_8(dst, tmp, 8, stride, rounding);
378 break;
379 case 11:
380 Ops->H_Pass_Avrg_Up_8(tmp, src, 9, stride, rounding);
381 Ops->V_Pass_8(dst, tmp, 8, stride, rounding);
382 break;
383 case 12:
384 Ops->V_Pass_Avrg_Up_8(dst, src, 8, stride, rounding);
385 break;
386 case 13:
387 Ops->H_Pass_Avrg_8(tmp, src, 9, stride, rounding);
388 Ops->V_Pass_Avrg_Up_8(dst, tmp, 8, stride, rounding);
389 break;
390 case 14:
391 Ops->H_Pass_8(tmp, src, 9, stride, rounding);
392 Ops->V_Pass_Avrg_Up_8( dst, tmp, 8, stride, rounding);
393 break;
394 case 15:
395 Ops->H_Pass_Avrg_Up_8(tmp, src, 9, stride, rounding);
396 Ops->V_Pass_Avrg_Up_8(dst, tmp, 8, stride, rounding);
397 break;
398 }
399 }
400
401 #endif /* _XVID_QPEL_H_ */