[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.8 - (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 : chl 1.8 * $Id: mbprediction.h,v 1.7 2002/05/07 19:40:36 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.5 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 1.1
55 :     void add_acdc(MACROBLOCK *pMB,
56 : edgomez 1.5 uint32_t block,
57 :     int16_t dct_codes[64],
58 :     uint32_t iDcScaler,
59 :     int16_t predictors[8]);
60 : Isibaar 1.1
61 :    
62 :     void predict_acdc(MACROBLOCK *pMBs,
63 : edgomez 1.5 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 1.1
72 : chl 1.4 /* get_pmvdata returns the median predictor and nothing else */
73 :    
74 :     static __inline VECTOR get_pmv(const MACROBLOCK * const pMBs,
75 : edgomez 1.5 const uint32_t x,
76 :     const uint32_t y,
77 :     const uint32_t x_dim,
78 :     const uint32_t block)
79 : chl 1.4 {
80 :    
81 : edgomez 1.5 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 :    
87 :     static VECTOR zeroMV = {0,0};
88 :     uint32_t index = x + y * x_dim;
89 : chl 1.4
90 : edgomez 1.5 /* first row (special case) */
91 :     if (y == 0 && (block == 0 || block == 1))
92 :     {
93 : chl 1.4 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 1.5 }
106 : chl 1.4
107 :     /*
108 : edgomez 1.5 * 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 1.4
120 : edgomez 1.5 switch (block)
121 :     {
122 : chl 1.4 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 1.5 break;
132 : chl 1.4 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 1.5 break;
137 : chl 1.4 default:
138 :     xin1 = x; yin1 = y; vec1 = 2;
139 :     xin2 = x; yin2 = y; vec2 = 0;
140 :     xin3 = x; yin3 = y; vec3 = 1;
141 : edgomez 1.5 }
142 : chl 1.4
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 1.5 /* median,minimum */
172 : chl 1.4
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 1.1 /* 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 1.5 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 1.1 {
189 : edgomez 1.5
190 :     /*
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 :    
203 :     int xin1, xin2, xin3;
204 :     int yin1, yin2, yin3;
205 :     int vec1, vec2, vec3;
206 :    
207 :     uint32_t index = x + y * x_dim;
208 : chl 1.8 const VECTOR zeroMV = { 0,0 };
209 : Isibaar 1.1
210 : chl 1.8 // first row of blocks (special case)
211 : edgomez 1.5 if (y == 0 && (block == 0 || block == 1))
212 :     {
213 : Isibaar 1.1 if ((x == 0) && (block == 0)) // first column, first block
214 :     {
215 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
216 : chl 1.8 psad[0] = 0;
217 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
218 : Isibaar 1.1 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 1.8 psad[2] = psad[3] = MV_MAX_ERROR;
226 : Isibaar 1.1 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 1.8 psad[2] = psad[3] = MV_MAX_ERROR;
234 : Isibaar 1.1 return 0;
235 :     }
236 : edgomez 1.5 }
237 : Isibaar 1.1
238 :     /*
239 : edgomez 1.5 * 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 1.1
251 : edgomez 1.5 switch (block)
252 :     {
253 : Isibaar 1.1 case 0:
254 : edgomez 1.5 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 1.1 break;
258 :     case 1:
259 : edgomez 1.5 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 1.1 case 2:
264 : edgomez 1.5 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 1.1 default:
269 : edgomez 1.5 xin1 = x; yin1 = y; vec1 = 2;
270 :     xin2 = x; yin2 = y; vec2 = 0;
271 :     xin3 = x; yin3 = y; vec3 = 1;
272 :     }
273 : Isibaar 1.1
274 :    
275 : chl 1.8 if (xin1 < 0 || xin1 >= (int32_t)x_dim)
276 : Isibaar 1.1 {
277 : chl 1.7 pmv[1] = zeroMV;
278 : Isibaar 1.1 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 : chl 1.8 if (xin2 < 0 || xin2 >= (int32_t)x_dim)
287 : Isibaar 1.1 {
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 : chl 1.8 if (xin3 < 0 || xin3 >= (int32_t)x_dim)
298 : Isibaar 1.1 {
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 1.7 {
310 :     pmv[0]=pmv[1];
311 : chl 1.8 psad[0]=MIN( MIN(psad[1],psad[2]), psad[3]);
312 : chl 1.7 return 1;
313 : Isibaar 1.1 }
314 :    
315 : edgomez 1.5 /* median,minimum */
316 : Isibaar 1.1
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 : chl 1.8 psad[0]=MIN( MIN(psad[1],psad[2]), psad[3]);
320 : edgomez 1.5
321 : Isibaar 1.1 return 0;
322 :     }
323 : chl 1.4
324 : Isibaar 1.1
325 :    
326 :     #endif /* _MBPREDICTION_H_ */

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