Parent Directory
|
Revision Log
Revision 1159 - (view) (download)
1 : | edgomez | 1142 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | * - Motion Estimation shared functions - | ||
5 : | * | ||
6 : | * Copyright(C) 2002 Christoph Lampert <gruel@web.de> | ||
7 : | * 2002 Michael Militzer <michael@xvid.org> | ||
8 : | * 2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net> | ||
9 : | * | ||
10 : | * This program is free software ; you can redistribute it and/or modify | ||
11 : | * it under the terms of the GNU General Public License as published by | ||
12 : | * the Free Software Foundation ; either version 2 of the License, or | ||
13 : | * (at your option) any later version. | ||
14 : | * | ||
15 : | * This program is distributed in the hope that it will be useful, | ||
16 : | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
17 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 : | * GNU General Public License for more details. | ||
19 : | * | ||
20 : | * You should have received a copy of the GNU General Public License | ||
21 : | * along with this program ; if not, write to the Free Software | ||
22 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 : | * | ||
24 : | syskin | 1159 | * $Id: motion_inlines.h,v 1.1.2.3 2003-09-29 16:58:37 syskin Exp $ |
25 : | edgomez | 1142 | * |
26 : | ****************************************************************************/ | ||
27 : | |||
28 : | #ifndef _MOTION_INLINES_ | ||
29 : | #define _MOTION_INLINES_ | ||
30 : | |||
31 : | #include <stdlib.h> | ||
32 : | |||
33 : | /* | ||
34 : | * Calculate the min/max range | ||
35 : | * relative to the _MACROBLOCK_ position | ||
36 : | */ | ||
37 : | static void __inline | ||
38 : | get_range(int32_t * const min_dx, | ||
39 : | int32_t * const max_dx, | ||
40 : | int32_t * const min_dy, | ||
41 : | int32_t * const max_dy, | ||
42 : | const uint32_t x, | ||
43 : | const uint32_t y, | ||
44 : | uint32_t block_sz, /* block dimension, 3(8) or 4(16) */ | ||
45 : | const uint32_t width, | ||
46 : | const uint32_t height, | ||
47 : | const uint32_t fcode, | ||
48 : | const int precision, /* 2 for qpel, 1 for halfpel */ | ||
49 : | const int rrv) | ||
50 : | { | ||
51 : | int k; | ||
52 : | const int search_range = 16 << fcode; | ||
53 : | int high = search_range - 1; | ||
54 : | int low = -search_range; | ||
55 : | |||
56 : | if (rrv) { | ||
57 : | high = RRV_MV_SCALEUP(high); | ||
58 : | low = RRV_MV_SCALEUP(low); | ||
59 : | block_sz++; | ||
60 : | } | ||
61 : | |||
62 : | k = (int)(width - (x<<block_sz))<<precision; | ||
63 : | *max_dx = MIN(high, k); | ||
64 : | k = (int)(height - (y<<block_sz))<<precision; | ||
65 : | *max_dy = MIN(high, k); | ||
66 : | |||
67 : | k = (-(int)((x+1)<<block_sz))<<precision; | ||
68 : | *min_dx = MAX(low, k); | ||
69 : | k = (-(int)((y+1)<<block_sz))<<precision; | ||
70 : | *min_dy = MAX(low, k); | ||
71 : | } | ||
72 : | |||
73 : | /* mv.length table */ | ||
74 : | static const int mvtab[64] = { | ||
75 : | 1, 2, 3, 4, 6, 7, 7, 7, | ||
76 : | 9, 9, 9, 10, 10, 10, 10, 10, | ||
77 : | 10, 10, 10, 10, 10, 10, 10, 10, | ||
78 : | 10, 11, 11, 11, 11, 11, 11, 12, | ||
79 : | 12, 12, 12, 12, 12, 12, 12, 12, | ||
80 : | 12, 12, 12, 12, 12, 12, 12, 12, | ||
81 : | syskin | 1159 | 12, 12, 12, 12, 12, 12, 12, 12 |
82 : | edgomez | 1142 | }; |
83 : | |||
84 : | static __inline uint32_t | ||
85 : | d_mv_bits(int x, int y, const VECTOR pred, const uint32_t iFcode, const int qpel, const int rrv) | ||
86 : | { | ||
87 : | int bits; | ||
88 : | const int q = (1 << (iFcode - 1)) - 1; | ||
89 : | |||
90 : | x <<= qpel; | ||
91 : | y <<= qpel; | ||
92 : | if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); } | ||
93 : | |||
94 : | x -= pred.x; | ||
95 : | bits = (x != 0 ? iFcode:0); | ||
96 : | x = abs(x); | ||
97 : | x += q; | ||
98 : | x >>= (iFcode - 1); | ||
99 : | bits += mvtab[x]; | ||
100 : | |||
101 : | y -= pred.y; | ||
102 : | bits += (y != 0 ? iFcode:0); | ||
103 : | y = abs(y); | ||
104 : | y += q; | ||
105 : | y >>= (iFcode - 1); | ||
106 : | bits += mvtab[y]; | ||
107 : | |||
108 : | return bits; | ||
109 : | } | ||
110 : | |||
111 : | static __inline const uint8_t * | ||
112 : | GetReference(const int x, const int y, const SearchData * const data) | ||
113 : | { | ||
114 : | const int picture = ((x&1)<<1) | (y&1); | ||
115 : | const int offset = (x>>1) + (y>>1)*data->iEdgedWidth; | ||
116 : | return data->RefP[picture] + offset; | ||
117 : | } | ||
118 : | |||
119 : | static __inline const uint8_t * | ||
120 : | GetReferenceB(const int x, const int y, const uint32_t dir, const SearchData * const data) | ||
121 : | { | ||
122 : | /* dir : 0 = forward, 1 = backward */ | ||
123 : | const uint8_t *const *const direction = ( dir == 0 ? data->RefP : data->b_RefP ); | ||
124 : | const int picture = ((x&1)<<1) | (y&1); | ||
125 : | const int offset = (x>>1) + (y>>1)*data->iEdgedWidth; | ||
126 : | return direction[picture] + offset; | ||
127 : | } | ||
128 : | |||
129 : | static __inline void | ||
130 : | ZeroMacroblockP(MACROBLOCK *pMB, const int32_t sad) | ||
131 : | { | ||
132 : | pMB->mode = MODE_INTER; | ||
133 : | pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = zeroMV; | ||
134 : | pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = zeroMV; | ||
135 : | pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad; | ||
136 : | syskin | 1158 | pMB->mcsel = 0; |
137 : | edgomez | 1142 | } |
138 : | |||
139 : | /* check if given vector is equal to any vector checked before */ | ||
140 : | static __inline int | ||
141 : | syskin | 1158 | vector_repeats(const VECTOR * const pmv, const unsigned int i) |
142 : | edgomez | 1142 | { |
143 : | unsigned int j; | ||
144 : | for (j = 0; j < i; j++) | ||
145 : | if (MVequal(pmv[i], pmv[j])) return 1; /* same vector has been checked already */ | ||
146 : | return 0; | ||
147 : | } | ||
148 : | |||
149 : | /* make a binary mask that prevents diamonds/squares | ||
150 : | from checking a vector which has been checked as a prediction */ | ||
151 : | static __inline int | ||
152 : | syskin | 1158 | make_mask(const VECTOR * const pmv, const unsigned int i, const unsigned int current) |
153 : | edgomez | 1142 | { |
154 : | unsigned int mask = 255, j; | ||
155 : | for (j = 0; j < i; j++) { | ||
156 : | if (pmv[current].x == pmv[j].x) { | ||
157 : | if (pmv[current].y == pmv[j].y + iDiamondSize) mask &= ~4; | ||
158 : | else if (pmv[current].y == pmv[j].y - iDiamondSize) mask &= ~8; | ||
159 : | } else | ||
160 : | if (pmv[current].y == pmv[j].y) { | ||
161 : | if (pmv[current].x == pmv[j].x + iDiamondSize) mask &= ~1; | ||
162 : | else if (pmv[current].x == pmv[j].x - iDiamondSize) mask &= ~2; | ||
163 : | } | ||
164 : | } | ||
165 : | return mask; | ||
166 : | } | ||
167 : | |||
168 : | #endif /* _MOTION_INLINES_ */ |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |