[cvs] / xvidcore / src / prediction / mbprediction.h Repository:
ViewVC logotype

Annotation of /xvidcore/src/prediction/mbprediction.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (view) (download)

1 : edgomez 1.5 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - MB prediction header file -
5 :     *
6 :     * This program is an implementation of a part of one or more MPEG-4
7 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
8 :     * to use this software module in hardware or software products are
9 :     * advised that its use may infringe existing patents or copyrights, and
10 :     * any such use would be at such party's own risk. The original
11 :     * developer of this software module and his/her company, and subsequent
12 :     * editors and their companies, will have no liability for use of this
13 :     * software or modifications or derivatives thereof.
14 :     *
15 :     * This program is free software; you can redistribute it and/or modify
16 :     * it under the terms of the GNU General Public License as published by
17 :     * the xvid_free Software Foundation; either version 2 of the License, or
18 :     * (at your option) any later version.
19 :     *
20 :     * This program is distributed in the hope that it will be useful,
21 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 :     * GNU General Public License for more details.
24 :     *
25 :     * You should have received a copy of the GNU General Public License
26 :     * along with this program; if not, write to the xvid_free Software
27 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 :     *
29 : edgomez 1.9 * $Id: mbprediction.h,v 1.8 2002/05/07 19:59:10 chl Exp $
30 : edgomez 1.5 *
31 :     *************************************************************************/
32 :    
33 : Isibaar 1.1 #ifndef _MBPREDICTION_H_
34 :     #define _MBPREDICTION_H_
35 :    
36 :     #include "../portab.h"
37 :     #include "../decoder.h"
38 :     #include "../global.h"
39 :    
40 :     #define MIN(X, Y) ((X)<(Y)?(X):(Y))
41 :     #define MAX(X, Y) ((X)>(Y)?(X):(Y))
42 :    
43 : edgomez 1.5 /* very large value */
44 : Isibaar 1.1 #define MV_MAX_ERROR (4096 * 256)
45 :    
46 :     #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
47 :    
48 : edgomez 1.9 void MBPrediction(FRAMEINFO * frame, /* <-- The parameter for ACDC and MV prediction */
49 :    
50 :     uint32_t x_pos, /* <-- The x position of the MB to be searched */
51 :    
52 :     uint32_t y_pos, /* <-- The y position of the MB to be searched */
53 :    
54 :     uint32_t x_dim, /* <-- Number of macroblocks in a row */
55 :    
56 :     int16_t * qcoeff); /* <-> The quantized DCT coefficients */
57 :    
58 :     void add_acdc(MACROBLOCK * pMB,
59 :     uint32_t block,
60 :     int16_t dct_codes[64],
61 :     uint32_t iDcScaler,
62 :     int16_t predictors[8]);
63 :    
64 :    
65 :     void predict_acdc(MACROBLOCK * pMBs,
66 :     uint32_t x,
67 :     uint32_t y,
68 :     uint32_t mb_width,
69 :     uint32_t block,
70 :     int16_t qcoeff[64],
71 :     uint32_t current_quant,
72 :     int32_t iDcScaler,
73 :     int16_t predictors[8]);
74 : Isibaar 1.1
75 : chl 1.4 /* get_pmvdata returns the median predictor and nothing else */
76 :    
77 : edgomez 1.9 static __inline VECTOR
78 :     get_pmv(const MACROBLOCK * const pMBs,
79 :     const uint32_t x,
80 :     const uint32_t y,
81 :     const uint32_t x_dim,
82 :     const uint32_t block)
83 : chl 1.4 {
84 :    
85 : edgomez 1.5 int xin1, xin2, xin3;
86 :     int yin1, yin2, yin3;
87 :     int vec1, vec2, vec3;
88 : edgomez 1.9 VECTOR lneigh, tneigh, trneigh; /* left neighbour, top neighbour, topright neighbour */
89 : edgomez 1.5 VECTOR median;
90 :    
91 : edgomez 1.9 static VECTOR zeroMV = { 0, 0 };
92 : edgomez 1.5 uint32_t index = x + y * x_dim;
93 : chl 1.4
94 : edgomez 1.5 /* first row (special case) */
95 : edgomez 1.9 if (y == 0 && (block == 0 || block == 1)) {
96 :     if ((x == 0) && (block == 0)) // first column, first block
97 :     {
98 : chl 1.4 return zeroMV;
99 :     }
100 : edgomez 1.9 if (block == 1) // second block; has only a left neighbour
101 : chl 1.4 {
102 :     return pMBs[index].mvs[0];
103 : edgomez 1.9 } else { /* block==0, but x!=0, so again, there is a left neighbour */
104 :    
105 :     return pMBs[index - 1].mvs[1];
106 : chl 1.4 }
107 : edgomez 1.5 }
108 : chl 1.4
109 :     /*
110 : edgomez 1.5 * MODE_INTER, vm18 page 48
111 :     * MODE_INTER4V vm18 page 51
112 :     *
113 :     * (x,y-1) (x+1,y-1)
114 :     * [ | ] [ | ]
115 :     * [ 2 | 3 ] [ 2 | ]
116 :     *
117 :     * (x-1,y) (x,y) (x+1,y)
118 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
119 :     * [ | 3 ] [ 2 | 3 ] [ | ]
120 :     */
121 : chl 1.4
122 : edgomez 1.9 switch (block) {
123 : chl 1.4 case 0:
124 : edgomez 1.9 xin1 = x - 1;
125 :     yin1 = y;
126 :     vec1 = 1; /* left */
127 :     xin2 = x;
128 :     yin2 = y - 1;
129 :     vec2 = 2; /* top */
130 :     xin3 = x + 1;
131 :     yin3 = y - 1;
132 :     vec3 = 2; /* top right */
133 : chl 1.4 break;
134 :     case 1:
135 : edgomez 1.9 xin1 = x;
136 :     yin1 = y;
137 :     vec1 = 0;
138 :     xin2 = x;
139 :     yin2 = y - 1;
140 :     vec2 = 3;
141 :     xin3 = x + 1;
142 :     yin3 = y - 1;
143 :     vec3 = 2;
144 : edgomez 1.5 break;
145 : chl 1.4 case 2:
146 : edgomez 1.9 xin1 = x - 1;
147 :     yin1 = y;
148 :     vec1 = 3;
149 :     xin2 = x;
150 :     yin2 = y;
151 :     vec2 = 0;
152 :     xin3 = x;
153 :     yin3 = y;
154 :     vec3 = 1;
155 : edgomez 1.5 break;
156 : chl 1.4 default:
157 : edgomez 1.9 xin1 = x;
158 :     yin1 = y;
159 :     vec1 = 2;
160 :     xin2 = x;
161 :     yin2 = y;
162 :     vec2 = 0;
163 :     xin3 = x;
164 :     yin3 = y;
165 :     vec3 = 1;
166 : edgomez 1.5 }
167 : chl 1.4
168 :    
169 : edgomez 1.9 if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t) x_dim) {
170 :     lneigh = zeroMV;
171 :     } else {
172 :     lneigh = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
173 : chl 1.4 }
174 :    
175 : edgomez 1.9 if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t) x_dim) {
176 : chl 1.4 tneigh = zeroMV;
177 : edgomez 1.9 } else {
178 :     tneigh = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
179 : chl 1.4 }
180 :    
181 : edgomez 1.9 if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t) x_dim) {
182 : chl 1.4 trneigh = zeroMV;
183 : edgomez 1.9 } else {
184 : chl 1.4 trneigh = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
185 :     }
186 :    
187 : edgomez 1.5 /* median,minimum */
188 : edgomez 1.9
189 :     median.x =
190 :     MIN(MAX(lneigh.x, tneigh.x),
191 :     MIN(MAX(tneigh.x, trneigh.x), MAX(lneigh.x, trneigh.x)));
192 :     median.y =
193 :     MIN(MAX(lneigh.y, tneigh.y),
194 :     MIN(MAX(tneigh.y, trneigh.y), MAX(lneigh.y, trneigh.y)));
195 : chl 1.4 return median;
196 :     }
197 :    
198 :    
199 : Isibaar 1.1 /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD
200 :     instead of only Median MV */
201 :    
202 : edgomez 1.9 static __inline int
203 :     get_pmvdata(const MACROBLOCK * const pMBs,
204 :     const uint32_t x,
205 :     const uint32_t y,
206 :     const uint32_t x_dim,
207 :     const uint32_t block,
208 :     VECTOR * const pmv,
209 :     int32_t * const psad)
210 : Isibaar 1.1 {
211 : edgomez 1.5
212 :     /*
213 :     * pmv are filled with:
214 :     * [0]: Median (or whatever is correct in a special case)
215 :     * [1]: left neighbour
216 :     * [2]: top neighbour
217 :     * [3]: topright neighbour
218 :     * psad are filled with:
219 :     * [0]: minimum of [1] to [3]
220 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
221 :     * [2]: top neighbour's SAD
222 :     * [3]: topright neighbour's SAD
223 :     */
224 :    
225 :     int xin1, xin2, xin3;
226 :     int yin1, yin2, yin3;
227 :     int vec1, vec2, vec3;
228 :    
229 :     uint32_t index = x + y * x_dim;
230 : edgomez 1.9 const VECTOR zeroMV = { 0, 0 };
231 : Isibaar 1.1
232 : chl 1.8 // first row of blocks (special case)
233 : edgomez 1.9 if (y == 0 && (block == 0 || block == 1)) {
234 :     if ((x == 0) && (block == 0)) // first column, first block
235 :     {
236 : Isibaar 1.1 pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
237 : chl 1.8 psad[0] = 0;
238 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
239 : Isibaar 1.1 return 0;
240 :     }
241 : edgomez 1.9 if (block == 1) // second block; has only a left neighbour
242 : Isibaar 1.1 {
243 :     pmv[0] = pmv[1] = pMBs[index].mvs[0];
244 :     pmv[2] = pmv[3] = zeroMV;
245 :     psad[0] = psad[1] = pMBs[index].sad8[0];
246 : chl 1.8 psad[2] = psad[3] = MV_MAX_ERROR;
247 : Isibaar 1.1 return 0;
248 : edgomez 1.9 } else { /* block==0, but x!=0, so again, there is a left neighbour */
249 :    
250 :     pmv[0] = pmv[1] = pMBs[index - 1].mvs[1];
251 : Isibaar 1.1 pmv[2] = pmv[3] = zeroMV;
252 : edgomez 1.9 psad[0] = psad[1] = pMBs[index - 1].sad8[1];
253 : chl 1.8 psad[2] = psad[3] = MV_MAX_ERROR;
254 : Isibaar 1.1 return 0;
255 :     }
256 : edgomez 1.5 }
257 : Isibaar 1.1
258 :     /*
259 : edgomez 1.5 * MODE_INTER, vm18 page 48
260 :     * MODE_INTER4V vm18 page 51
261 :     *
262 :     * (x,y-1) (x+1,y-1)
263 :     * [ | ] [ | ]
264 :     * [ 2 | 3 ] [ 2 | ]
265 :     *
266 :     * (x-1,y) (x,y) (x+1,y)
267 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
268 :     * [ | 3 ] [ 2 | 3 ] [ | ]
269 :     */
270 : Isibaar 1.1
271 : edgomez 1.9 switch (block) {
272 : Isibaar 1.1 case 0:
273 : edgomez 1.9 xin1 = x - 1;
274 :     yin1 = y;
275 :     vec1 = 1; /* left */
276 :     xin2 = x;
277 :     yin2 = y - 1;
278 :     vec2 = 2; /* top */
279 :     xin3 = x + 1;
280 :     yin3 = y - 1;
281 :     vec3 = 2; /* top right */
282 : Isibaar 1.1 break;
283 :     case 1:
284 : edgomez 1.9 xin1 = x;
285 :     yin1 = y;
286 :     vec1 = 0;
287 :     xin2 = x;
288 :     yin2 = y - 1;
289 :     vec2 = 3;
290 :     xin3 = x + 1;
291 :     yin3 = y - 1;
292 :     vec3 = 2;
293 : edgomez 1.5 break;
294 : Isibaar 1.1 case 2:
295 : edgomez 1.9 xin1 = x - 1;
296 :     yin1 = y;
297 :     vec1 = 3;
298 :     xin2 = x;
299 :     yin2 = y;
300 :     vec2 = 0;
301 :     xin3 = x;
302 :     yin3 = y;
303 :     vec3 = 1;
304 : edgomez 1.5 break;
305 : Isibaar 1.1 default:
306 : edgomez 1.9 xin1 = x;
307 :     yin1 = y;
308 :     vec1 = 2;
309 :     xin2 = x;
310 :     yin2 = y;
311 :     vec2 = 0;
312 :     xin3 = x;
313 :     yin3 = y;
314 :     vec3 = 1;
315 : edgomez 1.5 }
316 : Isibaar 1.1
317 :    
318 : edgomez 1.9 if (xin1 < 0 || xin1 >= (int32_t) x_dim) {
319 : chl 1.7 pmv[1] = zeroMV;
320 : Isibaar 1.1 psad[1] = MV_MAX_ERROR;
321 : edgomez 1.9 } else {
322 :     pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
323 :     psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1];
324 : Isibaar 1.1 }
325 :    
326 : edgomez 1.9 if (xin2 < 0 || xin2 >= (int32_t) x_dim) {
327 : Isibaar 1.1 pmv[2] = zeroMV;
328 :     psad[2] = MV_MAX_ERROR;
329 : edgomez 1.9 } else {
330 :     pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
331 :     psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2];
332 : Isibaar 1.1 }
333 :    
334 : edgomez 1.9 if (xin3 < 0 || xin3 >= (int32_t) x_dim) {
335 : Isibaar 1.1 pmv[3] = zeroMV;
336 :     psad[3] = MV_MAX_ERROR;
337 : edgomez 1.9 } else {
338 : Isibaar 1.1 pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
339 : edgomez 1.9 psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3];
340 : Isibaar 1.1 }
341 :    
342 : edgomez 1.9 if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
343 :     pmv[0] = pmv[1];
344 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
345 : chl 1.7 return 1;
346 : Isibaar 1.1 }
347 :    
348 : edgomez 1.5 /* median,minimum */
349 : edgomez 1.9
350 :     pmv[0].x =
351 :     MIN(MAX(pmv[1].x, pmv[2].x),
352 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
353 :     pmv[0].y =
354 :     MIN(MAX(pmv[1].y, pmv[2].y),
355 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
356 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
357 : edgomez 1.5
358 : Isibaar 1.1 return 0;
359 :     }
360 : chl 1.4
361 : Isibaar 1.1
362 :    
363 : edgomez 1.9 #endif /* _MBPREDICTION_H_ */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4