Parent Directory
|
Revision Log
Revision 1.4 - (view) (download)
1 : | Isibaar | 1.1 | #ifndef _MBPREDICTION_H_ |
2 : | #define _MBPREDICTION_H_ | ||
3 : | |||
4 : | #include "../portab.h" | ||
5 : | #include "../decoder.h" | ||
6 : | #include "../global.h" | ||
7 : | |||
8 : | #define MIN(X, Y) ((X)<(Y)?(X):(Y)) | ||
9 : | #define MAX(X, Y) ((X)>(Y)?(X):(Y)) | ||
10 : | |||
11 : | // very large value | ||
12 : | #define MV_MAX_ERROR (4096 * 256) | ||
13 : | |||
14 : | #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) | ||
15 : | |||
16 : | suxen_drol | 1.3 | void MBPrediction(FRAMEINFO *frame, /* <-- the parameter for ACDC and MV prediction */ |
17 : | Isibaar | 1.1 | uint32_t x_pos, /* <-- The x position of the MB to be searched */ |
18 : | uint32_t y_pos, /* <-- The y position of the MB to be searched */ | ||
19 : | uint32_t x_dim, /* <-- Number of macroblocks in a row */ | ||
20 : | suxen_drol | 1.3 | int16_t *qcoeff /* <-> The quantized DCT coefficients */ |
21 : | Isibaar | 1.1 | ); |
22 : | |||
23 : | void add_acdc(MACROBLOCK *pMB, | ||
24 : | uint32_t block, | ||
25 : | int16_t dct_codes[64], | ||
26 : | uint32_t iDcScaler, | ||
27 : | int16_t predictors[8]); | ||
28 : | |||
29 : | |||
30 : | void predict_acdc(MACROBLOCK *pMBs, | ||
31 : | uint32_t x, uint32_t y, uint32_t mb_width, | ||
32 : | uint32_t block, | ||
33 : | int16_t qcoeff[64], | ||
34 : | uint32_t current_quant, | ||
35 : | int32_t iDcScaler, | ||
36 : | int16_t predictors[8]); | ||
37 : | |||
38 : | chl | 1.4 | /* get_pmvdata returns the median predictor and nothing else */ |
39 : | |||
40 : | static __inline VECTOR get_pmv(const MACROBLOCK * const pMBs, | ||
41 : | const uint32_t x, const uint32_t y, | ||
42 : | const uint32_t x_dim, | ||
43 : | const uint32_t block) | ||
44 : | { | ||
45 : | |||
46 : | int xin1, xin2, xin3; | ||
47 : | int yin1, yin2, yin3; | ||
48 : | int vec1, vec2, vec3; | ||
49 : | VECTOR lneigh,tneigh,trneigh; /* left neighbour, top neighbour, topright neighbour */ | ||
50 : | VECTOR median; | ||
51 : | |||
52 : | static VECTOR zeroMV = {0,0}; | ||
53 : | uint32_t index = x + y * x_dim; | ||
54 : | // zeroMV.x = zeroMV.y = 0; | ||
55 : | |||
56 : | // first row (special case) | ||
57 : | if (y == 0 && (block == 0 || block == 1)) | ||
58 : | { | ||
59 : | if ((x == 0) && (block == 0)) // first column, first block | ||
60 : | { | ||
61 : | return zeroMV; | ||
62 : | } | ||
63 : | if (block == 1) // second block; has only a left neighbour | ||
64 : | { | ||
65 : | return pMBs[index].mvs[0]; | ||
66 : | } | ||
67 : | else /* block==0, but x!=0, so again, there is a left neighbour*/ | ||
68 : | { | ||
69 : | return pMBs[index-1].mvs[1]; | ||
70 : | } | ||
71 : | } | ||
72 : | |||
73 : | /* | ||
74 : | MODE_INTER, vm18 page 48 | ||
75 : | MODE_INTER4V vm18 page 51 | ||
76 : | |||
77 : | (x,y-1) (x+1,y-1) | ||
78 : | [ | ] [ | ] | ||
79 : | [ 2 | 3 ] [ 2 | ] | ||
80 : | |||
81 : | (x-1,y) (x,y) (x+1,y) | ||
82 : | [ | 1 ] [ 0 | 1 ] [ 0 | ] | ||
83 : | [ | 3 ] [ 2 | 3 ] [ | ] | ||
84 : | */ | ||
85 : | |||
86 : | switch (block) | ||
87 : | { | ||
88 : | case 0: | ||
89 : | xin1 = x - 1; yin1 = y; vec1 = 1; /* left */ | ||
90 : | xin2 = x; yin2 = y - 1; vec2 = 2; /* top */ | ||
91 : | xin3 = x + 1; yin3 = y - 1; vec3 = 2; /* top right */ | ||
92 : | break; | ||
93 : | case 1: | ||
94 : | xin1 = x; yin1 = y; vec1 = 0; | ||
95 : | xin2 = x; yin2 = y - 1; vec2 = 3; | ||
96 : | xin3 = x + 1; yin3 = y - 1; vec3 = 2; | ||
97 : | break; | ||
98 : | case 2: | ||
99 : | xin1 = x - 1; yin1 = y; vec1 = 3; | ||
100 : | xin2 = x; yin2 = y; vec2 = 0; | ||
101 : | xin3 = x; yin3 = y; vec3 = 1; | ||
102 : | break; | ||
103 : | default: | ||
104 : | xin1 = x; yin1 = y; vec1 = 2; | ||
105 : | xin2 = x; yin2 = y; vec2 = 0; | ||
106 : | xin3 = x; yin3 = y; vec3 = 1; | ||
107 : | } | ||
108 : | |||
109 : | |||
110 : | if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t)x_dim) | ||
111 : | { | ||
112 : | lneigh = zeroMV; | ||
113 : | } | ||
114 : | else | ||
115 : | { | ||
116 : | lneigh = pMBs[xin1 + yin1 * x_dim].mvs[vec1]; | ||
117 : | } | ||
118 : | |||
119 : | if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t)x_dim) | ||
120 : | { | ||
121 : | tneigh = zeroMV; | ||
122 : | } | ||
123 : | else | ||
124 : | { | ||
125 : | tneigh = pMBs[xin2 + yin2 * x_dim].mvs[vec2]; | ||
126 : | } | ||
127 : | |||
128 : | if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t)x_dim) | ||
129 : | { | ||
130 : | trneigh = zeroMV; | ||
131 : | } | ||
132 : | else | ||
133 : | { | ||
134 : | trneigh = pMBs[xin3 + yin3 * x_dim].mvs[vec3]; | ||
135 : | } | ||
136 : | |||
137 : | // median,minimum | ||
138 : | |||
139 : | median.x = MIN(MAX(lneigh.x, tneigh.x), MIN(MAX(tneigh.x, trneigh.x), MAX(lneigh.x, trneigh.x))); | ||
140 : | median.y = MIN(MAX(lneigh.y, tneigh.y), MIN(MAX(tneigh.y, trneigh.y), MAX(lneigh.y, trneigh.y))); | ||
141 : | return median; | ||
142 : | } | ||
143 : | |||
144 : | |||
145 : | Isibaar | 1.1 | /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD |
146 : | instead of only Median MV */ | ||
147 : | |||
148 : | static __inline int get_pmvdata(const MACROBLOCK * const pMBs, | ||
149 : | const uint32_t x, const uint32_t y, | ||
150 : | const uint32_t x_dim, | ||
151 : | const uint32_t block, | ||
152 : | VECTOR * const pmv, | ||
153 : | int32_t * const psad) | ||
154 : | { | ||
155 : | /* pmv are filled with: | ||
156 : | [0]: Median (or whatever is correct in a special case) | ||
157 : | [1]: left neighbour | ||
158 : | [2]: top neighbour, | ||
159 : | [3]: topright neighbour, | ||
160 : | psad are filled with: | ||
161 : | [0]: minimum of [1] to [3] | ||
162 : | [1]: left neighbour's SAD // [1] to [3] are actually not needed | ||
163 : | [2]: top neighbour's SAD, | ||
164 : | [3]: topright neighbour's SAD, | ||
165 : | */ | ||
166 : | |||
167 : | int xin1, xin2, xin3; | ||
168 : | int yin1, yin2, yin3; | ||
169 : | int vec1, vec2, vec3; | ||
170 : | |||
171 : | static VECTOR zeroMV; | ||
172 : | uint32_t index = x + y * x_dim; | ||
173 : | zeroMV.x = zeroMV.y = 0; | ||
174 : | |||
175 : | // first row (special case) | ||
176 : | if (y == 0 && (block == 0 || block == 1)) | ||
177 : | { | ||
178 : | if ((x == 0) && (block == 0)) // first column, first block | ||
179 : | { | ||
180 : | pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV; | ||
181 : | psad[0] = psad[1] = psad[2] = psad[3] = MV_MAX_ERROR; | ||
182 : | return 0; | ||
183 : | } | ||
184 : | if (block == 1) // second block; has only a left neighbour | ||
185 : | { | ||
186 : | pmv[0] = pmv[1] = pMBs[index].mvs[0]; | ||
187 : | pmv[2] = pmv[3] = zeroMV; | ||
188 : | psad[0] = psad[1] = pMBs[index].sad8[0]; | ||
189 : | psad[2] = psad[3] = MV_MAX_ERROR; | ||
190 : | return 0; | ||
191 : | } | ||
192 : | else /* block==0, but x!=0, so again, there is a left neighbour*/ | ||
193 : | { | ||
194 : | pmv[0] = pmv[1] = pMBs[index-1].mvs[1]; | ||
195 : | pmv[2] = pmv[3] = zeroMV; | ||
196 : | psad[0] = psad[1] = pMBs[index-1].sad8[1]; | ||
197 : | psad[2] = psad[3] = MV_MAX_ERROR; | ||
198 : | return 0; | ||
199 : | } | ||
200 : | } | ||
201 : | |||
202 : | /* | ||
203 : | MODE_INTER, vm18 page 48 | ||
204 : | MODE_INTER4V vm18 page 51 | ||
205 : | |||
206 : | (x,y-1) (x+1,y-1) | ||
207 : | [ | ] [ | ] | ||
208 : | [ 2 | 3 ] [ 2 | ] | ||
209 : | |||
210 : | (x-1,y) (x,y) (x+1,y) | ||
211 : | [ | 1 ] [ 0 | 1 ] [ 0 | ] | ||
212 : | [ | 3 ] [ 2 | 3 ] [ | ] | ||
213 : | */ | ||
214 : | |||
215 : | switch (block) | ||
216 : | { | ||
217 : | case 0: | ||
218 : | xin1 = x - 1; yin1 = y; vec1 = 1; /* left */ | ||
219 : | xin2 = x; yin2 = y - 1; vec2 = 2; /* top */ | ||
220 : | xin3 = x + 1; yin3 = y - 1; vec3 = 2; /* top right */ | ||
221 : | break; | ||
222 : | case 1: | ||
223 : | xin1 = x; yin1 = y; vec1 = 0; | ||
224 : | xin2 = x; yin2 = y - 1; vec2 = 3; | ||
225 : | xin3 = x + 1; yin3 = y - 1; vec3 = 2; | ||
226 : | break; | ||
227 : | case 2: | ||
228 : | xin1 = x - 1; yin1 = y; vec1 = 3; | ||
229 : | xin2 = x; yin2 = y; vec2 = 0; | ||
230 : | xin3 = x; yin3 = y; vec3 = 1; | ||
231 : | break; | ||
232 : | default: | ||
233 : | xin1 = x; yin1 = y; vec1 = 2; | ||
234 : | xin2 = x; yin2 = y; vec2 = 0; | ||
235 : | xin3 = x; yin3 = y; vec3 = 1; | ||
236 : | } | ||
237 : | |||
238 : | |||
239 : | if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t)x_dim) | ||
240 : | { | ||
241 : | pmv[1] = zeroMV; | ||
242 : | psad[1] = MV_MAX_ERROR; | ||
243 : | } | ||
244 : | else | ||
245 : | { | ||
246 : | pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1]; | ||
247 : | psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1]; | ||
248 : | } | ||
249 : | |||
250 : | if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t)x_dim) | ||
251 : | { | ||
252 : | pmv[2] = zeroMV; | ||
253 : | psad[2] = MV_MAX_ERROR; | ||
254 : | } | ||
255 : | else | ||
256 : | { | ||
257 : | pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2]; | ||
258 : | psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2]; | ||
259 : | } | ||
260 : | |||
261 : | if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t)x_dim) | ||
262 : | { | ||
263 : | pmv[3] = zeroMV; | ||
264 : | psad[3] = MV_MAX_ERROR; | ||
265 : | } | ||
266 : | else | ||
267 : | { | ||
268 : | pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3]; | ||
269 : | psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3]; | ||
270 : | } | ||
271 : | |||
272 : | if ( (MVequal(pmv[1],pmv[2])) && (MVequal(pmv[1],pmv[3])) ) | ||
273 : | { pmv[0]=pmv[1]; | ||
274 : | psad[0]=psad[1]; | ||
275 : | return 1; | ||
276 : | } | ||
277 : | |||
278 : | // median,minimum | ||
279 : | |||
280 : | 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))); | ||
281 : | 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))); | ||
282 : | psad[0]=MIN(MIN(psad[1],psad[2]),psad[3]); | ||
283 : | return 0; | ||
284 : | } | ||
285 : | chl | 1.4 | |
286 : | Isibaar | 1.1 | |
287 : | |||
288 : | #endif /* _MBPREDICTION_H_ */ |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |