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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 165 - (view) (download)

1 : edgomez 149 /**************************************************************************
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 : chl 165 * $Id: mbprediction.h,v 1.7 2002-05-07 19:40:36 chl Exp $
30 : edgomez 149 *
31 :     *************************************************************************/
32 :    
33 : Isibaar 3 #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 149 /* very large value */
44 : Isibaar 3 #define MV_MAX_ERROR (4096 * 256)
45 :    
46 :     #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
47 :    
48 : edgomez 149 void MBPrediction(
49 :     FRAMEINFO *frame, /* <-- The parameter for ACDC and MV prediction */
50 :     uint32_t x_pos, /* <-- The x position of the MB to be searched */
51 :     uint32_t y_pos, /* <-- The y position of the MB to be searched */
52 :     uint32_t x_dim, /* <-- Number of macroblocks in a row */
53 :     int16_t *qcoeff); /* <-> The quantized DCT coefficients */
54 : Isibaar 3
55 :     void add_acdc(MACROBLOCK *pMB,
56 : edgomez 149 uint32_t block,
57 :     int16_t dct_codes[64],
58 :     uint32_t iDcScaler,
59 :     int16_t predictors[8]);
60 : Isibaar 3
61 :    
62 :     void predict_acdc(MACROBLOCK *pMBs,
63 : edgomez 149 uint32_t x,
64 :     uint32_t y,
65 :     uint32_t mb_width,
66 :     uint32_t block,
67 :     int16_t qcoeff[64],
68 :     uint32_t current_quant,
69 :     int32_t iDcScaler,
70 :     int16_t predictors[8]);
71 : Isibaar 3
72 : chl 139 /* get_pmvdata returns the median predictor and nothing else */
73 :    
74 :     static __inline VECTOR get_pmv(const MACROBLOCK * const pMBs,
75 : edgomez 149 const uint32_t x,
76 :     const uint32_t y,
77 :     const uint32_t x_dim,
78 :     const uint32_t block)
79 : chl 139 {
80 :    
81 : edgomez 149 int xin1, xin2, xin3;
82 :     int yin1, yin2, yin3;
83 :     int vec1, vec2, vec3;
84 :     VECTOR lneigh,tneigh,trneigh; /* left neighbour, top neighbour, topright neighbour */
85 :     VECTOR median;
86 : chl 139
87 : edgomez 149 static VECTOR zeroMV = {0,0};
88 :     uint32_t index = x + y * x_dim;
89 : chl 139
90 : edgomez 149 /* first row (special case) */
91 :     if (y == 0 && (block == 0 || block == 1))
92 :     {
93 : chl 139 if ((x == 0) && (block == 0)) // first column, first block
94 :     {
95 :     return zeroMV;
96 :     }
97 :     if (block == 1) // second block; has only a left neighbour
98 :     {
99 :     return pMBs[index].mvs[0];
100 :     }
101 :     else /* block==0, but x!=0, so again, there is a left neighbour*/
102 :     {
103 :     return pMBs[index-1].mvs[1];
104 :     }
105 : edgomez 149 }
106 : chl 139
107 :     /*
108 : edgomez 149 * MODE_INTER, vm18 page 48
109 :     * MODE_INTER4V vm18 page 51
110 :     *
111 :     * (x,y-1) (x+1,y-1)
112 :     * [ | ] [ | ]
113 :     * [ 2 | 3 ] [ 2 | ]
114 :     *
115 :     * (x-1,y) (x,y) (x+1,y)
116 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
117 :     * [ | 3 ] [ 2 | 3 ] [ | ]
118 :     */
119 : chl 139
120 : edgomez 149 switch (block)
121 :     {
122 : chl 139 case 0:
123 :     xin1 = x - 1; yin1 = y; vec1 = 1; /* left */
124 :     xin2 = x; yin2 = y - 1; vec2 = 2; /* top */
125 :     xin3 = x + 1; yin3 = y - 1; vec3 = 2; /* top right */
126 :     break;
127 :     case 1:
128 :     xin1 = x; yin1 = y; vec1 = 0;
129 :     xin2 = x; yin2 = y - 1; vec2 = 3;
130 :     xin3 = x + 1; yin3 = y - 1; vec3 = 2;
131 : edgomez 149 break;
132 : chl 139 case 2:
133 :     xin1 = x - 1; yin1 = y; vec1 = 3;
134 :     xin2 = x; yin2 = y; vec2 = 0;
135 :     xin3 = x; yin3 = y; vec3 = 1;
136 : edgomez 149 break;
137 : chl 139 default:
138 :     xin1 = x; yin1 = y; vec1 = 2;
139 :     xin2 = x; yin2 = y; vec2 = 0;
140 :     xin3 = x; yin3 = y; vec3 = 1;
141 : edgomez 149 }
142 : chl 139
143 :    
144 :     if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t)x_dim)
145 :     {
146 :     lneigh = zeroMV;
147 :     }
148 :     else
149 :     {
150 :     lneigh = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
151 :     }
152 :    
153 :     if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t)x_dim)
154 :     {
155 :     tneigh = zeroMV;
156 :     }
157 :     else
158 :     {
159 :     tneigh = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
160 :     }
161 :    
162 :     if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t)x_dim)
163 :     {
164 :     trneigh = zeroMV;
165 :     }
166 :     else
167 :     {
168 :     trneigh = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
169 :     }
170 :    
171 : edgomez 149 /* median,minimum */
172 : chl 139
173 :     median.x = MIN(MAX(lneigh.x, tneigh.x), MIN(MAX(tneigh.x, trneigh.x), MAX(lneigh.x, trneigh.x)));
174 :     median.y = MIN(MAX(lneigh.y, tneigh.y), MIN(MAX(tneigh.y, trneigh.y), MAX(lneigh.y, trneigh.y)));
175 :     return median;
176 :     }
177 :    
178 :    
179 : Isibaar 3 /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD
180 :     instead of only Median MV */
181 :    
182 :     static __inline int get_pmvdata(const MACROBLOCK * const pMBs,
183 : edgomez 149 const uint32_t x, const uint32_t y,
184 :     const uint32_t x_dim,
185 :     const uint32_t block,
186 :     VECTOR * const pmv,
187 :     int32_t * const psad)
188 : Isibaar 3 {
189 :    
190 : edgomez 149 /*
191 :     * pmv are filled with:
192 :     * [0]: Median (or whatever is correct in a special case)
193 :     * [1]: left neighbour
194 :     * [2]: top neighbour
195 :     * [3]: topright neighbour
196 :     * psad are filled with:
197 :     * [0]: minimum of [1] to [3]
198 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
199 :     * [2]: top neighbour's SAD
200 :     * [3]: topright neighbour's SAD
201 :     */
202 : Isibaar 3
203 : edgomez 149 int xin1, xin2, xin3;
204 :     int yin1, yin2, yin3;
205 :     int vec1, vec2, vec3;
206 : Isibaar 3
207 : edgomez 149 static VECTOR zeroMV;
208 :     uint32_t index = x + y * x_dim;
209 :     zeroMV.x = zeroMV.y = 0;
210 :    
211 : Isibaar 3 // first row (special case)
212 : edgomez 149 if (y == 0 && (block == 0 || block == 1))
213 :     {
214 : Isibaar 3 if ((x == 0) && (block == 0)) // first column, first block
215 :     {
216 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
217 : chl 165 psad[0] = psad[1] = psad[2] = psad[3] = 0;
218 : Isibaar 3 return 0;
219 :     }
220 :     if (block == 1) // second block; has only a left neighbour
221 :     {
222 :     pmv[0] = pmv[1] = pMBs[index].mvs[0];
223 :     pmv[2] = pmv[3] = zeroMV;
224 :     psad[0] = psad[1] = pMBs[index].sad8[0];
225 : chl 165 psad[2] = psad[3] = 0;
226 : Isibaar 3 return 0;
227 :     }
228 :     else /* block==0, but x!=0, so again, there is a left neighbour*/
229 :     {
230 :     pmv[0] = pmv[1] = pMBs[index-1].mvs[1];
231 :     pmv[2] = pmv[3] = zeroMV;
232 :     psad[0] = psad[1] = pMBs[index-1].sad8[1];
233 : chl 165 psad[2] = psad[3] = 0;
234 : Isibaar 3 return 0;
235 :     }
236 : edgomez 149 }
237 : Isibaar 3
238 :     /*
239 : edgomez 149 * MODE_INTER, vm18 page 48
240 :     * MODE_INTER4V vm18 page 51
241 :     *
242 :     * (x,y-1) (x+1,y-1)
243 :     * [ | ] [ | ]
244 :     * [ 2 | 3 ] [ 2 | ]
245 :     *
246 :     * (x-1,y) (x,y) (x+1,y)
247 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
248 :     * [ | 3 ] [ 2 | 3 ] [ | ]
249 :     */
250 : Isibaar 3
251 : edgomez 149 switch (block)
252 :     {
253 : Isibaar 3 case 0:
254 : edgomez 149 xin1 = x - 1; yin1 = y; vec1 = 1; /* left */
255 :     xin2 = x; yin2 = y - 1; vec2 = 2; /* top */
256 :     xin3 = x + 1; yin3 = y - 1; vec3 = 2; /* top right */
257 : Isibaar 3 break;
258 :     case 1:
259 : edgomez 149 xin1 = x; yin1 = y; vec1 = 0;
260 :     xin2 = x; yin2 = y - 1; vec2 = 3;
261 :     xin3 = x + 1; yin3 = y - 1; vec3 = 2;
262 :     break;
263 : Isibaar 3 case 2:
264 : edgomez 149 xin1 = x - 1; yin1 = y; vec1 = 3;
265 :     xin2 = x; yin2 = y; vec2 = 0;
266 :     xin3 = x; yin3 = y; vec3 = 1;
267 :     break;
268 : Isibaar 3 default:
269 : edgomez 149 xin1 = x; yin1 = y; vec1 = 2;
270 :     xin2 = x; yin2 = y; vec2 = 0;
271 :     xin3 = x; yin3 = y; vec3 = 1;
272 :     }
273 : Isibaar 3
274 :    
275 :     if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t)x_dim)
276 :     {
277 : chl 165 pmv[1] = zeroMV;
278 : Isibaar 3 psad[1] = MV_MAX_ERROR;
279 :     }
280 :     else
281 :     {
282 :     pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
283 :     psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1];
284 :     }
285 :    
286 :     if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t)x_dim)
287 :     {
288 :     pmv[2] = zeroMV;
289 :     psad[2] = MV_MAX_ERROR;
290 :     }
291 :     else
292 :     {
293 :     pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
294 :     psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2];
295 :     }
296 :    
297 :     if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t)x_dim)
298 :     {
299 :     pmv[3] = zeroMV;
300 :     psad[3] = MV_MAX_ERROR;
301 :     }
302 :     else
303 :     {
304 :     pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
305 :     psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3];
306 :     }
307 :    
308 :     if ( (MVequal(pmv[1],pmv[2])) && (MVequal(pmv[1],pmv[3])) )
309 : chl 165 {
310 :     pmv[0]=pmv[1];
311 :     psad[0]=MIN(MIN(psad[1],psad[2]),psad[3]);
312 :     return 1;
313 : Isibaar 3 }
314 :    
315 : edgomez 149 /* median,minimum */
316 : Isibaar 3
317 :     pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x), MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
318 :     pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y), MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
319 :     psad[0]=MIN(MIN(psad[1],psad[2]),psad[3]);
320 : edgomez 149
321 : Isibaar 3 return 0;
322 :     }
323 :    
324 :    
325 : chl 139
326 : Isibaar 3 #endif /* _MBPREDICTION_H_ */

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