Mercurial > libavcodec.hg
annotate motion_est.c @ 1757:3906ddbaffec libavcodec
optimization & bugfix extracted from the 4k line diff between ffmpeg 0.4.7 and http://www.alicestreet.com/ffh263.html
the other parts of the diff where
1. spelling fixes (rejected as only a small part of it could be applied automatically)
2. cosmetics (reindention, function reordering, var renaming, ...) with bugs (rejected)
3. rtp related stuff (rejetced as it breaks several codecs)
4. some changes to the intra/inter decission & scene change detection (quality tests needed first)
author | michael |
---|---|
date | Sat, 24 Jan 2004 23:47:33 +0000 |
parents | 67949dc3117b |
children | 5f42b809bc04 |
rev | line source |
---|---|
0 | 1 /* |
2 * Motion estimation | |
429 | 3 * Copyright (c) 2000,2001 Fabrice Bellard. |
1739
07a484280a82
copyright year update of the files i touched and remembered, things look annoyingly unmaintained otherwise
michael
parents:
1729
diff
changeset
|
4 * Copyright (c) 2002-2004 Michael Niedermayer |
0 | 5 * |
6 * | |
429 | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2 of the License, or (at your option) any later version. | |
0 | 11 * |
429 | 12 * This library is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Lesser General Public License for more details. | |
0 | 16 * |
429 | 17 * You should have received a copy of the GNU Lesser General Public |
18 * License along with this library; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
20 * |
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
21 * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at> |
0 | 22 */ |
1106 | 23 |
24 /** | |
25 * @file motion_est.c | |
26 * Motion estimation. | |
27 */ | |
28 | |
0 | 29 #include <stdlib.h> |
30 #include <stdio.h> | |
1426 | 31 #include <limits.h> |
0 | 32 #include "avcodec.h" |
33 #include "dsputil.h" | |
34 #include "mpegvideo.h" | |
35 | |
1422
efeed6e29f9b
oooooops, having 2 Eterms open and doing cvs diff in one and cvs commit in the other sucks, especially if they are in different directories (MPlayer/main/libavcodec vs. ffmpeg/libavcodec)
michaelni
parents:
1421
diff
changeset
|
36 //#undef NDEBUG |
efeed6e29f9b
oooooops, having 2 Eterms open and doing cvs diff in one and cvs commit in the other sucks, especially if they are in different directories (MPlayer/main/libavcodec vs. ffmpeg/libavcodec)
michaelni
parents:
1421
diff
changeset
|
37 //#include <assert.h> |
936 | 38 |
455 | 39 #define SQ(a) ((a)*(a)) |
284 | 40 |
455 | 41 #define P_LEFT P[1] |
42 #define P_TOP P[2] | |
43 #define P_TOPRIGHT P[3] | |
44 #define P_MEDIAN P[4] | |
45 #define P_MV1 P[9] | |
46 | |
936 | 47 static inline int sad_hpel_motion_search(MpegEncContext * s, |
48 int *mx_ptr, int *my_ptr, int dmin, | |
1708 | 49 int pred_x, int pred_y, uint8_t *src_data[3], |
50 uint8_t *ref_data[6], int stride, int uvstride, | |
51 int size, int h, uint8_t * const mv_penalty); | |
0 | 52 |
936 | 53 static inline int update_map_generation(MpegEncContext * s) |
54 { | |
55 s->me.map_generation+= 1<<(ME_MAP_MV_BITS*2); | |
56 if(s->me.map_generation==0){ | |
57 s->me.map_generation= 1<<(ME_MAP_MV_BITS*2); | |
58 memset(s->me.map, 0, sizeof(uint32_t)*ME_MAP_SIZE); | |
59 } | |
60 return s->me.map_generation; | |
61 } | |
62 | |
948 | 63 /* shape adaptive search stuff */ |
64 typedef struct Minima{ | |
65 int height; | |
66 int x, y; | |
67 int checked; | |
68 }Minima; | |
936 | 69 |
948 | 70 static int minima_cmp(const void *a, const void *b){ |
1057 | 71 const Minima *da = (const Minima *) a; |
72 const Minima *db = (const Minima *) b; | |
948 | 73 |
74 return da->height - db->height; | |
75 } | |
936 | 76 |
77 /* SIMPLE */ | |
78 #define RENAME(a) simple_ ## a | |
79 | |
80 #define CMP(d, x, y, size)\ | |
1708 | 81 d = cmp(s, src_y, (ref_y) + (x) + (y)*(stride), stride, h); |
936 | 82 |
83 #define CMP_HPEL(d, dx, dy, x, y, size)\ | |
84 {\ | |
85 const int dxy= (dx) + 2*(dy);\ | |
1708 | 86 hpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride, h);\ |
87 d = cmp_sub(s, s->me.scratchpad, src_y, stride, h);\ | |
936 | 88 } |
89 | |
1708 | 90 |
936 | 91 #define CMP_QPEL(d, dx, dy, x, y, size)\ |
92 {\ | |
93 const int dxy= (dx) + 4*(dy);\ | |
94 qpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride);\ | |
1708 | 95 d = cmp_sub(s, s->me.scratchpad, src_y, stride, h);\ |
936 | 96 } |
97 | |
98 #include "motion_est_template.c" | |
99 #undef RENAME | |
100 #undef CMP | |
101 #undef CMP_HPEL | |
102 #undef CMP_QPEL | |
103 #undef INIT | |
104 | |
105 /* SIMPLE CHROMA */ | |
106 #define RENAME(a) simple_chroma_ ## a | |
107 | |
108 #define CMP(d, x, y, size)\ | |
1708 | 109 d = cmp(s, src_y, (ref_y) + (x) + (y)*(stride), stride, h);\ |
936 | 110 if(chroma_cmp){\ |
111 int dxy= ((x)&1) + 2*((y)&1);\ | |
112 int c= ((x)>>1) + ((y)>>1)*uvstride;\ | |
113 \ | |
1708 | 114 chroma_hpel_put[0][dxy](s->me.scratchpad, ref_u + c, uvstride, h>>1);\ |
115 d += chroma_cmp(s, s->me.scratchpad, src_u, uvstride, h>>1);\ | |
116 chroma_hpel_put[0][dxy](s->me.scratchpad, ref_v + c, uvstride, h>>1);\ | |
117 d += chroma_cmp(s, s->me.scratchpad, src_v, uvstride, h>>1);\ | |
936 | 118 } |
119 | |
120 #define CMP_HPEL(d, dx, dy, x, y, size)\ | |
121 {\ | |
122 const int dxy= (dx) + 2*(dy);\ | |
1708 | 123 hpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride, h);\ |
124 d = cmp_sub(s, s->me.scratchpad, src_y, stride, h);\ | |
936 | 125 if(chroma_cmp_sub){\ |
126 int cxy= (dxy) | ((x)&1) | (2*((y)&1));\ | |
127 int c= ((x)>>1) + ((y)>>1)*uvstride;\ | |
1708 | 128 chroma_hpel_put[0][cxy](s->me.scratchpad, ref_u + c, uvstride, h>>1);\ |
129 d += chroma_cmp_sub(s, s->me.scratchpad, src_u, uvstride, h>>1);\ | |
130 chroma_hpel_put[0][cxy](s->me.scratchpad, ref_v + c, uvstride, h>>1);\ | |
131 d += chroma_cmp_sub(s, s->me.scratchpad, src_v, uvstride, h>>1);\ | |
936 | 132 }\ |
133 } | |
134 | |
135 #define CMP_QPEL(d, dx, dy, x, y, size)\ | |
136 {\ | |
137 const int dxy= (dx) + 4*(dy);\ | |
138 qpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride);\ | |
1708 | 139 d = cmp_sub(s, s->me.scratchpad, src_y, stride, h);\ |
936 | 140 if(chroma_cmp_sub){\ |
141 int cxy, c;\ | |
142 int cx= (4*(x) + (dx))/2;\ | |
143 int cy= (4*(y) + (dy))/2;\ | |
144 cx= (cx>>1)|(cx&1);\ | |
145 cy= (cy>>1)|(cy&1);\ | |
146 cxy= (cx&1) + 2*(cy&1);\ | |
147 c= ((cx)>>1) + ((cy)>>1)*uvstride;\ | |
1708 | 148 chroma_hpel_put[0][cxy](s->me.scratchpad, ref_u + c, uvstride, h>>1);\ |
149 d += chroma_cmp_sub(s, s->me.scratchpad, src_u, uvstride, h>>1);\ | |
150 chroma_hpel_put[0][cxy](s->me.scratchpad, ref_v + c, uvstride, h>>1);\ | |
151 d += chroma_cmp_sub(s, s->me.scratchpad, src_v, uvstride, h>>1);\ | |
936 | 152 }\ |
153 } | |
154 | |
155 #include "motion_est_template.c" | |
156 #undef RENAME | |
157 #undef CMP | |
158 #undef CMP_HPEL | |
159 #undef CMP_QPEL | |
160 #undef INIT | |
161 | |
162 /* SIMPLE DIRECT HPEL */ | |
163 #define RENAME(a) simple_direct_hpel_ ## a | |
164 //FIXME precalc divisions stuff | |
165 | |
166 #define CMP_DIRECT(d, dx, dy, x, y, size, cmp_func)\ | |
167 if((x) >= xmin && 2*(x) + (dx) <= 2*xmax && (y) >= ymin && 2*(y) + (dy) <= 2*ymax){\ | |
168 const int hx= 2*(x) + (dx);\ | |
169 const int hy= 2*(y) + (dy);\ | |
170 if(s->mv_type==MV_TYPE_8X8){\ | |
171 int i;\ | |
172 for(i=0; i<4; i++){\ | |
173 int fx = s->me.direct_basis_mv[i][0] + hx;\ | |
174 int fy = s->me.direct_basis_mv[i][1] + hy;\ | |
175 int bx = hx ? fx - s->me.co_located_mv[i][0] : s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + (i &1)*16;\ | |
176 int by = hy ? fy - s->me.co_located_mv[i][1] : s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + (i>>1)*16;\ | |
177 int fxy= (fx&1) + 2*(fy&1);\ | |
178 int bxy= (bx&1) + 2*(by&1);\ | |
179 \ | |
180 uint8_t *dst= s->me.scratchpad + 8*(i&1) + 8*stride*(i>>1);\ | |
181 hpel_put[1][fxy](dst, (ref_y ) + (fx>>1) + (fy>>1)*(stride), stride, 8);\ | |
1708 | 182 hpel_avg[1][bxy](dst, (ref_data[3]) + (bx>>1) + (by>>1)*(stride), stride, 8);\ |
936 | 183 }\ |
184 }else{\ | |
185 int fx = s->me.direct_basis_mv[0][0] + hx;\ | |
186 int fy = s->me.direct_basis_mv[0][1] + hy;\ | |
1050 | 187 int bx = hx ? fx - s->me.co_located_mv[0][0] : (s->me.co_located_mv[0][0]*(time_pb - time_pp)/time_pp);\ |
188 int by = hy ? fy - s->me.co_located_mv[0][1] : (s->me.co_located_mv[0][1]*(time_pb - time_pp)/time_pp);\ | |
936 | 189 int fxy= (fx&1) + 2*(fy&1);\ |
190 int bxy= (bx&1) + 2*(by&1);\ | |
1050 | 191 \ |
192 assert((fx>>1) + 16*s->mb_x >= -16);\ | |
193 assert((fy>>1) + 16*s->mb_y >= -16);\ | |
194 assert((fx>>1) + 16*s->mb_x <= s->width);\ | |
195 assert((fy>>1) + 16*s->mb_y <= s->height);\ | |
196 assert((bx>>1) + 16*s->mb_x >= -16);\ | |
197 assert((by>>1) + 16*s->mb_y >= -16);\ | |
198 assert((bx>>1) + 16*s->mb_x <= s->width);\ | |
199 assert((by>>1) + 16*s->mb_y <= s->height);\ | |
936 | 200 \ |
201 hpel_put[0][fxy](s->me.scratchpad, (ref_y ) + (fx>>1) + (fy>>1)*(stride), stride, 16);\ | |
1708 | 202 hpel_avg[0][bxy](s->me.scratchpad, (ref_data[3]) + (bx>>1) + (by>>1)*(stride), stride, 16);\ |
936 | 203 }\ |
1708 | 204 d = cmp_func(s, s->me.scratchpad, src_y, stride, 16);\ |
936 | 205 }else\ |
206 d= 256*256*256*32; | |
207 | |
208 | |
209 #define CMP_HPEL(d, dx, dy, x, y, size)\ | |
210 CMP_DIRECT(d, dx, dy, x, y, size, cmp_sub) | |
211 | |
212 #define CMP(d, x, y, size)\ | |
213 CMP_DIRECT(d, 0, 0, x, y, size, cmp) | |
214 | |
215 #include "motion_est_template.c" | |
216 #undef RENAME | |
217 #undef CMP | |
218 #undef CMP_HPEL | |
219 #undef CMP_QPEL | |
220 #undef INIT | |
221 #undef CMP_DIRECT | |
222 | |
223 /* SIMPLE DIRECT QPEL */ | |
224 #define RENAME(a) simple_direct_qpel_ ## a | |
225 | |
226 #define CMP_DIRECT(d, dx, dy, x, y, size, cmp_func)\ | |
227 if((x) >= xmin && 4*(x) + (dx) <= 4*xmax && (y) >= ymin && 4*(y) + (dy) <= 4*ymax){\ | |
228 const int qx= 4*(x) + (dx);\ | |
229 const int qy= 4*(y) + (dy);\ | |
230 if(s->mv_type==MV_TYPE_8X8){\ | |
231 int i;\ | |
232 for(i=0; i<4; i++){\ | |
233 int fx = s->me.direct_basis_mv[i][0] + qx;\ | |
234 int fy = s->me.direct_basis_mv[i][1] + qy;\ | |
235 int bx = qx ? fx - s->me.co_located_mv[i][0] : s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + (i &1)*16;\ | |
236 int by = qy ? fy - s->me.co_located_mv[i][1] : s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + (i>>1)*16;\ | |
237 int fxy= (fx&3) + 4*(fy&3);\ | |
238 int bxy= (bx&3) + 4*(by&3);\ | |
239 \ | |
240 uint8_t *dst= s->me.scratchpad + 8*(i&1) + 8*stride*(i>>1);\ | |
241 qpel_put[1][fxy](dst, (ref_y ) + (fx>>2) + (fy>>2)*(stride), stride);\ | |
1708 | 242 qpel_avg[1][bxy](dst, (ref_data[3]) + (bx>>2) + (by>>2)*(stride), stride);\ |
936 | 243 }\ |
244 }else{\ | |
245 int fx = s->me.direct_basis_mv[0][0] + qx;\ | |
246 int fy = s->me.direct_basis_mv[0][1] + qy;\ | |
247 int bx = qx ? fx - s->me.co_located_mv[0][0] : s->me.co_located_mv[0][0]*(time_pb - time_pp)/time_pp;\ | |
248 int by = qy ? fy - s->me.co_located_mv[0][1] : s->me.co_located_mv[0][1]*(time_pb - time_pp)/time_pp;\ | |
249 int fxy= (fx&3) + 4*(fy&3);\ | |
250 int bxy= (bx&3) + 4*(by&3);\ | |
251 \ | |
1053
f07fd48c23d4
direct blocksize in bframes fix (might fix qpel+bframe bug)
michaelni
parents:
1051
diff
changeset
|
252 qpel_put[1][fxy](s->me.scratchpad , (ref_y ) + (fx>>2) + (fy>>2)*(stride) , stride);\ |
f07fd48c23d4
direct blocksize in bframes fix (might fix qpel+bframe bug)
michaelni
parents:
1051
diff
changeset
|
253 qpel_put[1][fxy](s->me.scratchpad + 8 , (ref_y ) + (fx>>2) + (fy>>2)*(stride) + 8 , stride);\ |
f07fd48c23d4
direct blocksize in bframes fix (might fix qpel+bframe bug)
michaelni
parents:
1051
diff
changeset
|
254 qpel_put[1][fxy](s->me.scratchpad + 8*stride, (ref_y ) + (fx>>2) + (fy>>2)*(stride) + 8*stride, stride);\ |
f07fd48c23d4
direct blocksize in bframes fix (might fix qpel+bframe bug)
michaelni
parents:
1051
diff
changeset
|
255 qpel_put[1][fxy](s->me.scratchpad + 8 + 8*stride, (ref_y ) + (fx>>2) + (fy>>2)*(stride) + 8 + 8*stride, stride);\ |
1708 | 256 qpel_avg[1][bxy](s->me.scratchpad , (ref_data[3]) + (bx>>2) + (by>>2)*(stride) , stride);\ |
257 qpel_avg[1][bxy](s->me.scratchpad + 8 , (ref_data[3]) + (bx>>2) + (by>>2)*(stride) + 8 , stride);\ | |
258 qpel_avg[1][bxy](s->me.scratchpad + 8*stride, (ref_data[3]) + (bx>>2) + (by>>2)*(stride) + 8*stride, stride);\ | |
259 qpel_avg[1][bxy](s->me.scratchpad + 8 + 8*stride, (ref_data[3]) + (bx>>2) + (by>>2)*(stride) + 8 + 8*stride, stride);\ | |
936 | 260 }\ |
1708 | 261 d = cmp_func(s, s->me.scratchpad, src_y, stride, 16);\ |
936 | 262 }else\ |
263 d= 256*256*256*32; | |
264 | |
265 | |
266 #define CMP_QPEL(d, dx, dy, x, y, size)\ | |
267 CMP_DIRECT(d, dx, dy, x, y, size, cmp_sub) | |
268 | |
269 #define CMP(d, x, y, size)\ | |
270 CMP_DIRECT(d, 0, 0, x, y, size, cmp) | |
271 | |
272 #include "motion_est_template.c" | |
273 #undef RENAME | |
274 #undef CMP | |
275 #undef CMP_HPEL | |
276 #undef CMP_QPEL | |
277 #undef INIT | |
278 #undef CMP__DIRECT | |
279 | |
280 static inline int get_penalty_factor(MpegEncContext *s, int type){ | |
1013 | 281 switch(type&0xFF){ |
936 | 282 default: |
283 case FF_CMP_SAD: | |
1013 | 284 return s->qscale*2; |
936 | 285 case FF_CMP_DCT: |
1013 | 286 return s->qscale*3; |
936 | 287 case FF_CMP_SATD: |
1013 | 288 return s->qscale*6; |
1007 | 289 case FF_CMP_SSE: |
1013 | 290 return s->qscale*s->qscale*2; |
1007 | 291 case FF_CMP_BIT: |
292 return 1; | |
293 case FF_CMP_RD: | |
1013 | 294 case FF_CMP_PSNR: |
295 return (s->qscale*s->qscale*185 + 64)>>7; | |
936 | 296 } |
297 } | |
298 | |
299 void ff_init_me(MpegEncContext *s){ | |
1729 | 300 ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp); |
301 ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp); | |
302 ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); | |
303 ff_set_cmp(&s->dsp, s->dsp.mb_cmp, s->avctx->mb_cmp); | |
936 | 304 |
305 if(s->flags&CODEC_FLAG_QPEL){ | |
306 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) | |
307 s->me.sub_motion_search= simple_chroma_qpel_motion_search; | |
308 else | |
309 s->me.sub_motion_search= simple_qpel_motion_search; | |
310 }else{ | |
311 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) | |
312 s->me.sub_motion_search= simple_chroma_hpel_motion_search; | |
1013 | 313 else if( s->avctx->me_sub_cmp == FF_CMP_SAD |
314 && s->avctx-> me_cmp == FF_CMP_SAD | |
315 && s->avctx-> mb_cmp == FF_CMP_SAD) | |
1708 | 316 s->me.sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles |
936 | 317 else |
318 s->me.sub_motion_search= simple_hpel_motion_search; | |
319 } | |
320 | |
321 if(s->avctx->me_cmp&FF_CMP_CHROMA){ | |
322 s->me.motion_search[0]= simple_chroma_epzs_motion_search; | |
323 s->me.motion_search[1]= simple_chroma_epzs_motion_search4; | |
1708 | 324 s->me.motion_search[4]= simple_chroma_epzs_motion_search2; |
936 | 325 }else{ |
326 s->me.motion_search[0]= simple_epzs_motion_search; | |
327 s->me.motion_search[1]= simple_epzs_motion_search4; | |
1708 | 328 s->me.motion_search[4]= simple_epzs_motion_search2; |
936 | 329 } |
954 | 330 |
331 if(s->avctx->me_pre_cmp&FF_CMP_CHROMA){ | |
332 s->me.pre_motion_search= simple_chroma_epzs_motion_search; | |
333 }else{ | |
334 s->me.pre_motion_search= simple_epzs_motion_search; | |
335 } | |
1013 | 336 |
337 if(s->flags&CODEC_FLAG_QPEL){ | |
338 if(s->avctx->mb_cmp&FF_CMP_CHROMA) | |
339 s->me.get_mb_score= simple_chroma_qpel_get_mb_score; | |
340 else | |
341 s->me.get_mb_score= simple_qpel_get_mb_score; | |
342 }else{ | |
343 if(s->avctx->mb_cmp&FF_CMP_CHROMA) | |
344 s->me.get_mb_score= simple_chroma_hpel_get_mb_score; | |
345 else | |
346 s->me.get_mb_score= simple_hpel_get_mb_score; | |
347 } | |
936 | 348 } |
349 | |
1419 | 350 #if 0 |
1064 | 351 static int pix_dev(uint8_t * pix, int line_size, int mean) |
284 | 352 { |
353 int s, i, j; | |
354 | |
355 s = 0; | |
356 for (i = 0; i < 16; i++) { | |
357 for (j = 0; j < 16; j += 8) { | |
358 s += ABS(pix[0]-mean); | |
359 s += ABS(pix[1]-mean); | |
360 s += ABS(pix[2]-mean); | |
361 s += ABS(pix[3]-mean); | |
362 s += ABS(pix[4]-mean); | |
363 s += ABS(pix[5]-mean); | |
364 s += ABS(pix[6]-mean); | |
365 s += ABS(pix[7]-mean); | |
366 pix += 8; | |
367 } | |
368 pix += line_size - 16; | |
369 } | |
370 return s; | |
371 } | |
1419 | 372 #endif |
284 | 373 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
374 static inline void no_motion_search(MpegEncContext * s, |
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
375 int *mx_ptr, int *my_ptr) |
0 | 376 { |
377 *mx_ptr = 16 * s->mb_x; | |
378 *my_ptr = 16 * s->mb_y; | |
379 } | |
380 | |
381 static int full_motion_search(MpegEncContext * s, | |
382 int *mx_ptr, int *my_ptr, int range, | |
324 | 383 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 384 { |
385 int x1, y1, x2, y2, xx, yy, x, y; | |
386 int mx, my, dmin, d; | |
1064 | 387 uint8_t *pix; |
0 | 388 |
389 xx = 16 * s->mb_x; | |
390 yy = 16 * s->mb_y; | |
391 x1 = xx - range + 1; /* we loose one pixel to avoid boundary pb with half pixel pred */ | |
392 if (x1 < xmin) | |
393 x1 = xmin; | |
394 x2 = xx + range - 1; | |
395 if (x2 > xmax) | |
396 x2 = xmax; | |
397 y1 = yy - range + 1; | |
398 if (y1 < ymin) | |
399 y1 = ymin; | |
400 y2 = yy + range - 1; | |
401 if (y2 > ymax) | |
402 y2 = ymax; | |
903 | 403 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 404 dmin = 0x7fffffff; |
405 mx = 0; | |
406 my = 0; | |
407 for (y = y1; y <= y2; y++) { | |
408 for (x = x1; x <= x2; x++) { | |
1708 | 409 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, |
410 s->linesize, 16); | |
0 | 411 if (d < dmin || |
412 (d == dmin && | |
413 (abs(x - xx) + abs(y - yy)) < | |
414 (abs(mx - xx) + abs(my - yy)))) { | |
415 dmin = d; | |
416 mx = x; | |
417 my = y; | |
418 } | |
419 } | |
420 } | |
421 | |
422 *mx_ptr = mx; | |
423 *my_ptr = my; | |
424 | |
425 #if 0 | |
426 if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) || | |
427 *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) { | |
428 fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr); | |
429 } | |
430 #endif | |
431 return dmin; | |
432 } | |
433 | |
434 | |
435 static int log_motion_search(MpegEncContext * s, | |
436 int *mx_ptr, int *my_ptr, int range, | |
324 | 437 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 438 { |
439 int x1, y1, x2, y2, xx, yy, x, y; | |
440 int mx, my, dmin, d; | |
1064 | 441 uint8_t *pix; |
0 | 442 |
443 xx = s->mb_x << 4; | |
444 yy = s->mb_y << 4; | |
445 | |
446 /* Left limit */ | |
447 x1 = xx - range; | |
448 if (x1 < xmin) | |
449 x1 = xmin; | |
450 | |
451 /* Right limit */ | |
452 x2 = xx + range; | |
453 if (x2 > xmax) | |
454 x2 = xmax; | |
455 | |
456 /* Upper limit */ | |
457 y1 = yy - range; | |
458 if (y1 < ymin) | |
459 y1 = ymin; | |
460 | |
461 /* Lower limit */ | |
462 y2 = yy + range; | |
463 if (y2 > ymax) | |
464 y2 = ymax; | |
465 | |
903 | 466 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 467 dmin = 0x7fffffff; |
468 mx = 0; | |
469 my = 0; | |
470 | |
471 do { | |
472 for (y = y1; y <= y2; y += range) { | |
473 for (x = x1; x <= x2; x += range) { | |
1708 | 474 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 475 if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
476 dmin = d; | |
477 mx = x; | |
478 my = y; | |
479 } | |
480 } | |
481 } | |
482 | |
483 range = range >> 1; | |
484 | |
485 x1 = mx - range; | |
486 if (x1 < xmin) | |
487 x1 = xmin; | |
488 | |
489 x2 = mx + range; | |
490 if (x2 > xmax) | |
491 x2 = xmax; | |
492 | |
493 y1 = my - range; | |
494 if (y1 < ymin) | |
495 y1 = ymin; | |
496 | |
497 y2 = my + range; | |
498 if (y2 > ymax) | |
499 y2 = ymax; | |
500 | |
501 } while (range >= 1); | |
502 | |
503 #ifdef DEBUG | |
504 fprintf(stderr, "log - MX: %d\tMY: %d\n", mx, my); | |
505 #endif | |
506 *mx_ptr = mx; | |
507 *my_ptr = my; | |
508 return dmin; | |
509 } | |
510 | |
511 static int phods_motion_search(MpegEncContext * s, | |
512 int *mx_ptr, int *my_ptr, int range, | |
324 | 513 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 514 { |
515 int x1, y1, x2, y2, xx, yy, x, y, lastx, d; | |
516 int mx, my, dminx, dminy; | |
1064 | 517 uint8_t *pix; |
0 | 518 |
519 xx = s->mb_x << 4; | |
520 yy = s->mb_y << 4; | |
521 | |
522 /* Left limit */ | |
523 x1 = xx - range; | |
524 if (x1 < xmin) | |
525 x1 = xmin; | |
526 | |
527 /* Right limit */ | |
528 x2 = xx + range; | |
529 if (x2 > xmax) | |
530 x2 = xmax; | |
531 | |
532 /* Upper limit */ | |
533 y1 = yy - range; | |
534 if (y1 < ymin) | |
535 y1 = ymin; | |
536 | |
537 /* Lower limit */ | |
538 y2 = yy + range; | |
539 if (y2 > ymax) | |
540 y2 = ymax; | |
541 | |
903 | 542 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 543 mx = 0; |
544 my = 0; | |
545 | |
546 x = xx; | |
547 y = yy; | |
548 do { | |
549 dminx = 0x7fffffff; | |
550 dminy = 0x7fffffff; | |
551 | |
552 lastx = x; | |
553 for (x = x1; x <= x2; x += range) { | |
1708 | 554 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 555 if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
556 dminx = d; | |
557 mx = x; | |
558 } | |
559 } | |
560 | |
561 x = lastx; | |
562 for (y = y1; y <= y2; y += range) { | |
1708 | 563 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 564 if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
565 dminy = d; | |
566 my = y; | |
567 } | |
568 } | |
569 | |
570 range = range >> 1; | |
571 | |
572 x = mx; | |
573 y = my; | |
574 x1 = mx - range; | |
575 if (x1 < xmin) | |
576 x1 = xmin; | |
577 | |
578 x2 = mx + range; | |
579 if (x2 > xmax) | |
580 x2 = xmax; | |
581 | |
582 y1 = my - range; | |
583 if (y1 < ymin) | |
584 y1 = ymin; | |
585 | |
586 y2 = my + range; | |
587 if (y2 > ymax) | |
588 y2 = ymax; | |
589 | |
590 } while (range >= 1); | |
591 | |
592 #ifdef DEBUG | |
593 fprintf(stderr, "phods - MX: %d\tMY: %d\n", mx, my); | |
594 #endif | |
595 | |
596 /* half pixel search */ | |
597 *mx_ptr = mx; | |
598 *my_ptr = my; | |
599 return dminy; | |
600 } | |
601 | |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
602 |
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
603 #define Z_THRESHOLD 256 |
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
604 |
936 | 605 #define CHECK_SAD_HALF_MV(suffix, x, y) \ |
455 | 606 {\ |
1708 | 607 d= s->dsp.pix_abs[size][(x?1:0)+(y?2:0)](NULL, pix, ptr+((x)>>1), stride, h);\ |
936 | 608 d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\ |
455 | 609 COPY3_IF_LT(dminh, d, dx, x, dy, y)\ |
610 } | |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
611 |
936 | 612 static inline int sad_hpel_motion_search(MpegEncContext * s, |
0 | 613 int *mx_ptr, int *my_ptr, int dmin, |
1708 | 614 int pred_x, int pred_y, uint8_t *src_data[3], |
615 uint8_t *ref_data[6], int stride, int uvstride, | |
616 int size, int h, uint8_t * const mv_penalty) | |
0 | 617 { |
936 | 618 uint32_t *score_map= s->me.score_map; |
619 const int penalty_factor= s->me.sub_penalty_factor; | |
1708 | 620 int mx, my, dminh; |
1064 | 621 uint8_t *pix, *ptr; |
1708 | 622 const int xmin= s->me.xmin; |
623 const int ymin= s->me.ymin; | |
624 const int xmax= s->me.xmax; | |
625 const int ymax= s->me.ymax; | |
455 | 626 |
936 | 627 if(s->me.skip){ |
455 | 628 // printf("S"); |
629 *mx_ptr = 0; | |
630 *my_ptr = 0; | |
631 return dmin; | |
632 } | |
633 // printf("N"); | |
634 | |
1708 | 635 pix = src_data[0]; |
455 | 636 |
294 | 637 mx = *mx_ptr; |
638 my = *my_ptr; | |
1708 | 639 ptr = ref_data[0] + (my * stride) + mx; |
455 | 640 |
294 | 641 dminh = dmin; |
642 | |
643 if (mx > xmin && mx < xmax && | |
644 my > ymin && my < ymax) { | |
455 | 645 int dx=0, dy=0; |
646 int d, pen_x, pen_y; | |
647 const int index= (my<<ME_MAP_SHIFT) + mx; | |
648 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; | |
649 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]; | |
650 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]; | |
651 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; | |
652 mx<<=1; | |
653 my<<=1; | |
294 | 654 |
655 | |
656 pen_x= pred_x + mx; | |
657 pen_y= pred_y + my; | |
658 | |
1708 | 659 ptr-= stride; |
455 | 660 if(t<=b){ |
936 | 661 CHECK_SAD_HALF_MV(y2 , 0, -1) |
455 | 662 if(l<=r){ |
936 | 663 CHECK_SAD_HALF_MV(xy2, -1, -1) |
455 | 664 if(t+r<=b+l){ |
936 | 665 CHECK_SAD_HALF_MV(xy2, +1, -1) |
1708 | 666 ptr+= stride; |
455 | 667 }else{ |
1708 | 668 ptr+= stride; |
936 | 669 CHECK_SAD_HALF_MV(xy2, -1, +1) |
455 | 670 } |
936 | 671 CHECK_SAD_HALF_MV(x2 , -1, 0) |
455 | 672 }else{ |
936 | 673 CHECK_SAD_HALF_MV(xy2, +1, -1) |
455 | 674 if(t+l<=b+r){ |
936 | 675 CHECK_SAD_HALF_MV(xy2, -1, -1) |
1708 | 676 ptr+= stride; |
455 | 677 }else{ |
1708 | 678 ptr+= stride; |
936 | 679 CHECK_SAD_HALF_MV(xy2, +1, +1) |
455 | 680 } |
936 | 681 CHECK_SAD_HALF_MV(x2 , +1, 0) |
455 | 682 } |
683 }else{ | |
684 if(l<=r){ | |
685 if(t+l<=b+r){ | |
936 | 686 CHECK_SAD_HALF_MV(xy2, -1, -1) |
1708 | 687 ptr+= stride; |
455 | 688 }else{ |
1708 | 689 ptr+= stride; |
936 | 690 CHECK_SAD_HALF_MV(xy2, +1, +1) |
455 | 691 } |
936 | 692 CHECK_SAD_HALF_MV(x2 , -1, 0) |
693 CHECK_SAD_HALF_MV(xy2, -1, +1) | |
455 | 694 }else{ |
695 if(t+r<=b+l){ | |
936 | 696 CHECK_SAD_HALF_MV(xy2, +1, -1) |
1708 | 697 ptr+= stride; |
455 | 698 }else{ |
1708 | 699 ptr+= stride; |
936 | 700 CHECK_SAD_HALF_MV(xy2, -1, +1) |
455 | 701 } |
936 | 702 CHECK_SAD_HALF_MV(x2 , +1, 0) |
703 CHECK_SAD_HALF_MV(xy2, +1, +1) | |
455 | 704 } |
936 | 705 CHECK_SAD_HALF_MV(y2 , 0, +1) |
455 | 706 } |
707 mx+=dx; | |
708 my+=dy; | |
294 | 709 |
710 }else{ | |
455 | 711 mx<<=1; |
712 my<<=1; | |
294 | 713 } |
714 | |
715 *mx_ptr = mx; | |
716 *my_ptr = my; | |
455 | 717 return dminh; |
294 | 718 } |
719 | |
455 | 720 static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4) |
294 | 721 { |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
722 const int xy= s->mb_x + s->mb_y*s->mb_stride; |
294 | 723 |
324 | 724 s->p_mv_table[xy][0] = mx; |
725 s->p_mv_table[xy][1] = my; | |
294 | 726 |
727 /* has allready been set to the 4 MV if 4MV is done */ | |
455 | 728 if(mv4){ |
294 | 729 int mot_xy= s->block_index[0]; |
730 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
731 s->current_picture.motion_val[0][mot_xy ][0]= mx; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
732 s->current_picture.motion_val[0][mot_xy ][1]= my; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
733 s->current_picture.motion_val[0][mot_xy+1][0]= mx; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
734 s->current_picture.motion_val[0][mot_xy+1][1]= my; |
294 | 735 |
736 mot_xy += s->block_wrap[0]; | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
737 s->current_picture.motion_val[0][mot_xy ][0]= mx; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
738 s->current_picture.motion_val[0][mot_xy ][1]= my; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
739 s->current_picture.motion_val[0][mot_xy+1][0]= mx; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
740 s->current_picture.motion_val[0][mot_xy+1][1]= my; |
294 | 741 } |
742 } | |
743 | |
1086 | 744 /** |
745 * get fullpel ME search limits. | |
746 */ | |
1708 | 747 static inline void get_limits(MpegEncContext *s, int x, int y) |
324 | 748 { |
1708 | 749 /* |
750 if(s->avctx->me_range) s->me.range= s->avctx->me_range >> 1; | |
751 else s->me.range= 16; | |
752 */ | |
324 | 753 if (s->unrestricted_mv) { |
1708 | 754 s->me.xmin = - x - 16; |
755 s->me.ymin = - y - 16; | |
756 s->me.xmax = - x + s->mb_width *16; | |
757 s->me.ymax = - y + s->mb_height*16; | |
324 | 758 } else { |
1708 | 759 s->me.xmin = - x; |
760 s->me.ymin = - y; | |
761 s->me.xmax = - x + s->mb_width *16 - 16; | |
762 s->me.ymax = - y + s->mb_height*16 - 16; | |
324 | 763 } |
764 } | |
765 | |
1708 | 766 static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) |
455 | 767 { |
1708 | 768 const int size= 1; |
769 const int h=8; | |
455 | 770 int block; |
771 int P[10][2]; | |
1013 | 772 int dmin_sum=0, mx4_sum=0, my4_sum=0; |
1162 | 773 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
1494
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
774 int same=1; |
1708 | 775 const int stride= s->linesize; |
776 const int uvstride= s->uvlinesize; | |
777 const int xmin= s->me.xmin; | |
778 const int ymin= s->me.ymin; | |
779 const int xmax= s->me.xmax; | |
780 const int ymax= s->me.ymax; | |
455 | 781 |
782 for(block=0; block<4; block++){ | |
783 int mx4, my4; | |
784 int pred_x4, pred_y4; | |
785 int dmin4; | |
786 static const int off[4]= {2, 1, 1, -1}; | |
787 const int mot_stride = s->block_wrap[0]; | |
788 const int mot_xy = s->block_index[block]; | |
1708 | 789 const int block_x= (block&1); |
790 const int block_y= (block>>1); | |
791 uint8_t *src_data[3]= { | |
792 s->new_picture.data[0] + 8*(2*s->mb_x + block_x) + stride *8*(2*s->mb_y + block_y), //FIXME chroma? | |
793 s->new_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y), | |
794 s->new_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y) | |
795 }; | |
796 uint8_t *ref_data[3]= { | |
797 s->last_picture.data[0] + 8*(2*s->mb_x + block_x) + stride *8*(2*s->mb_y + block_y), //FIXME chroma? | |
798 s->last_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y), | |
799 s->last_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y) | |
800 }; | |
801 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
802 P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
803 P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; |
455 | 804 |
1708 | 805 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
455 | 806 |
807 /* special case for first line */ | |
952 | 808 if (s->mb_y == 0 && block<2) { |
455 | 809 pred_x4= P_LEFT[0]; |
810 pred_y4= P_LEFT[1]; | |
811 } else { | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
812 P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
813 P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
814 P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
815 P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; |
1708 | 816 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift); |
817 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
818 if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift); | |
819 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
455 | 820 |
821 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
822 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
823 | |
1013 | 824 // if(s->out_format == FMT_H263){ |
455 | 825 pred_x4 = P_MEDIAN[0]; |
826 pred_y4 = P_MEDIAN[1]; | |
1013 | 827 #if 0 |
455 | 828 }else { /* mpeg1 at least */ |
829 pred_x4= P_LEFT[0]; | |
830 pred_y4= P_LEFT[1]; | |
831 } | |
1013 | 832 #endif |
455 | 833 } |
834 P_MV1[0]= mx; | |
835 P_MV1[1]= my; | |
836 | |
1708 | 837 dmin4 = s->me.motion_search[1](s, &mx4, &my4, P, pred_x4, pred_y4, |
838 src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty); | |
455 | 839 |
1708 | 840 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, |
841 pred_x4, pred_y4, src_data, ref_data, stride, uvstride, size, h, mv_penalty); | |
1038 | 842 |
1746 | 843 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0] |
844 && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE){ | |
1013 | 845 int dxy; |
1708 | 846 const int offset= ((block&1) + (block>>1)*stride)*8; |
1013 | 847 uint8_t *dest_y = s->me.scratchpad + offset; |
848 | |
849 if(s->quarter_sample){ | |
1745
fe5e2c14a04c
fixing twice added offset bug, was triggered by 4mv + sub_cmp != mb_cmp
michael
parents:
1739
diff
changeset
|
850 uint8_t *ref= ref_data[0] + (mx4>>2) + (my4>>2)*stride; |
1013 | 851 dxy = ((my4 & 3) << 2) | (mx4 & 3); |
852 | |
853 if(s->no_rounding) | |
1038 | 854 s->dsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y , ref , s->linesize); |
1013 | 855 else |
1708 | 856 s->dsp.put_qpel_pixels_tab [1][dxy](dest_y , ref , stride); |
1013 | 857 }else{ |
1745
fe5e2c14a04c
fixing twice added offset bug, was triggered by 4mv + sub_cmp != mb_cmp
michael
parents:
1739
diff
changeset
|
858 uint8_t *ref= ref_data[0] + (mx4>>1) + (my4>>1)*stride; |
1013 | 859 dxy = ((my4 & 1) << 1) | (mx4 & 1); |
860 | |
861 if(s->no_rounding) | |
1708 | 862 s->dsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h); |
1013 | 863 else |
1708 | 864 s->dsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h); |
1013 | 865 } |
866 dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*s->me.mb_penalty_factor; | |
867 }else | |
868 dmin_sum+= dmin4; | |
869 | |
870 if(s->quarter_sample){ | |
871 mx4_sum+= mx4/2; | |
872 my4_sum+= my4/2; | |
873 }else{ | |
874 mx4_sum+= mx4; | |
875 my4_sum+= my4; | |
876 } | |
877 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
878 s->current_picture.motion_val[0][ s->block_index[block] ][0]= mx4; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
879 s->current_picture.motion_val[0][ s->block_index[block] ][1]= my4; |
1494
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
880 |
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
881 if(mx4 != mx || my4 != my) same=0; |
1013 | 882 } |
883 | |
1494
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
884 if(same) |
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
885 return INT_MAX; |
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
886 |
1038 | 887 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ |
1708 | 888 dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, s->me.scratchpad, stride, 16); |
455 | 889 } |
1013 | 890 |
891 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
892 int dxy; | |
893 int mx, my; | |
894 int offset; | |
895 | |
896 mx= ff_h263_round_chroma(mx4_sum); | |
897 my= ff_h263_round_chroma(my4_sum); | |
898 dxy = ((my & 1) << 1) | (mx & 1); | |
899 | |
900 offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize; | |
901 | |
902 if(s->no_rounding){ | |
903 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); | |
904 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); | |
905 }else{ | |
906 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); | |
907 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); | |
908 } | |
909 | |
1708 | 910 dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad , s->uvlinesize, 8); |
911 dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad+8, s->uvlinesize, 8); | |
1013 | 912 } |
913 | |
914 switch(s->avctx->mb_cmp&0xFF){ | |
915 /*case FF_CMP_SSE: | |
916 return dmin_sum+ 32*s->qscale*s->qscale;*/ | |
917 case FF_CMP_RD: | |
918 return dmin_sum; | |
919 default: | |
920 return dmin_sum+ 11*s->me.mb_penalty_factor; | |
921 } | |
455 | 922 } |
923 | |
1708 | 924 static int interlaced_search(MpegEncContext *s, uint8_t *frame_src_data[3], uint8_t *frame_ref_data[3], |
925 int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int f_code, int mx, int my) | |
926 { | |
927 const int size=0; | |
928 const int h=8; | |
929 int block; | |
930 int P[10][2]; | |
931 uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; | |
932 int same=1; | |
933 const int stride= 2*s->linesize; | |
934 const int uvstride= 2*s->uvlinesize; | |
935 int dmin_sum= 0; | |
936 const int mot_stride= s->mb_stride; | |
937 const int xy= s->mb_x + s->mb_y*mot_stride; | |
938 | |
939 s->me.ymin>>=1; | |
940 s->me.ymax>>=1; | |
941 | |
942 for(block=0; block<2; block++){ | |
943 int field_select; | |
944 int best_dmin= INT_MAX; | |
945 int best_field= -1; | |
946 | |
947 uint8_t *src_data[3]= { | |
948 frame_src_data[0] + s-> linesize*block, | |
949 frame_src_data[1] + s->uvlinesize*block, | |
950 frame_src_data[2] + s->uvlinesize*block | |
951 }; | |
952 | |
953 for(field_select=0; field_select<2; field_select++){ | |
954 int dmin, mx_i, my_i, pred_x, pred_y; | |
955 uint8_t *ref_data[3]= { | |
956 frame_ref_data[0] + s-> linesize*field_select, | |
957 frame_ref_data[1] + s->uvlinesize*field_select, | |
958 frame_ref_data[2] + s->uvlinesize*field_select | |
959 }; | |
960 int16_t (*mv_table)[2]= mv_tables[block][field_select]; | |
961 | |
962 P_LEFT[0] = mv_table[xy - 1][0]; | |
963 P_LEFT[1] = mv_table[xy - 1][1]; | |
964 if(P_LEFT[0] > (s->me.xmax<<1)) P_LEFT[0] = (s->me.xmax<<1); | |
965 | |
966 pred_x= P_LEFT[0]; | |
967 pred_y= P_LEFT[1]; | |
968 | |
969 if(s->mb_y){ | |
970 P_TOP[0] = mv_table[xy - mot_stride][0]; | |
971 P_TOP[1] = mv_table[xy - mot_stride][1]; | |
972 P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; | |
973 P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; | |
974 if(P_TOP[1] > (s->me.ymax<<1)) P_TOP[1] = (s->me.ymax<<1); | |
975 if(P_TOPRIGHT[0] < (s->me.xmin<<1)) P_TOPRIGHT[0]= (s->me.xmin<<1); | |
976 if(P_TOPRIGHT[0] > (s->me.xmax<<1)) P_TOPRIGHT[0]= (s->me.xmax<<1); | |
977 if(P_TOPRIGHT[1] > (s->me.ymax<<1)) P_TOPRIGHT[1]= (s->me.ymax<<1); | |
978 | |
979 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
980 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
981 } | |
982 P_MV1[0]= mx; //FIXME not correct if block != field_select | |
983 P_MV1[1]= my / 2; | |
984 | |
985 dmin = s->me.motion_search[4](s, &mx_i, &my_i, P, pred_x, pred_y, | |
986 src_data, ref_data, stride, uvstride, mv_table, (1<<16)>>1, mv_penalty); | |
987 | |
988 dmin= s->me.sub_motion_search(s, &mx_i, &my_i, dmin, | |
989 pred_x, pred_y, src_data, ref_data, stride, uvstride, size, h, mv_penalty); | |
990 | |
991 mv_table[xy][0]= mx_i; | |
992 mv_table[xy][1]= my_i; | |
993 | |
1746 | 994 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0] |
995 && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE){ | |
1708 | 996 int dxy; |
997 | |
998 //FIXME chroma ME | |
999 uint8_t *ref= ref_data[0] + (mx_i>>1) + (my_i>>1)*stride; | |
1000 dxy = ((my_i & 1) << 1) | (mx_i & 1); | |
1001 | |
1002 if(s->no_rounding){ | |
1003 s->dsp.put_no_rnd_pixels_tab[size][dxy](s->me.scratchpad, ref , stride, h); | |
1004 }else{ | |
1005 s->dsp.put_pixels_tab [size][dxy](s->me.scratchpad, ref , stride, h); | |
1006 } | |
1007 dmin= s->dsp.mb_cmp[size](s, src_data[0], s->me.scratchpad, stride, h); | |
1008 dmin+= (mv_penalty[mx_i-pred_x] + mv_penalty[my_i-pred_y] + 1)*s->me.mb_penalty_factor; | |
1009 }else | |
1010 dmin+= s->me.mb_penalty_factor; //field_select bits | |
1011 | |
1012 dmin += field_select != block; //slightly prefer same field | |
1013 | |
1014 if(dmin < best_dmin){ | |
1015 best_dmin= dmin; | |
1016 best_field= field_select; | |
1017 } | |
1018 } | |
1019 { | |
1020 int16_t (*mv_table)[2]= mv_tables[block][best_field]; | |
1021 | |
1022 if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all | |
1023 if(mv_table[xy][1]&1) same=0; | |
1024 if(mv_table[xy][1]*2 != my) same=0; | |
1025 if(best_field != block) same=0; | |
1026 } | |
1027 | |
1028 field_select_tables[block][xy]= best_field; | |
1029 dmin_sum += best_dmin; | |
1030 } | |
1031 | |
1032 s->me.ymin<<=1; | |
1033 s->me.ymax<<=1; | |
1034 | |
1035 if(same) | |
1036 return INT_MAX; | |
1037 | |
1038 switch(s->avctx->mb_cmp&0xFF){ | |
1039 /*case FF_CMP_SSE: | |
1040 return dmin_sum+ 32*s->qscale*s->qscale;*/ | |
1041 case FF_CMP_RD: | |
1042 return dmin_sum; | |
1043 default: | |
1044 return dmin_sum+ 11*s->me.mb_penalty_factor; | |
1045 } | |
1046 } | |
1047 | |
324 | 1048 void ff_estimate_p_frame_motion(MpegEncContext * s, |
1049 int mb_x, int mb_y) | |
0 | 1050 { |
1064 | 1051 uint8_t *pix, *ppix; |
1708 | 1052 int sum, varc, vard, mx, my, dmin, xx, yy; |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
1053 int pred_x=0, pred_y=0; |
455 | 1054 int P[10][2]; |
280 | 1055 const int shift= 1+s->quarter_sample; |
294 | 1056 int mb_type=0; |
903 | 1057 uint8_t *ref_picture= s->last_picture.data[0]; |
1058 Picture * const pic= &s->current_picture; | |
1162 | 1059 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
1708 | 1060 const int stride= s->linesize; |
1061 const int uvstride= s->uvlinesize; | |
1062 uint8_t *src_data[3]= { | |
1063 s->new_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1064 s->new_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1065 s->new_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1066 }; | |
1067 uint8_t *ref_data[3]= { | |
1068 s->last_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1069 s->last_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1070 s->last_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1071 }; | |
1072 | |
936 | 1073 assert(s->quarter_sample==0 || s->quarter_sample==1); |
1074 | |
1075 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | |
1076 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | |
1013 | 1077 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
0 | 1078 |
1708 | 1079 get_limits(s, 16*mb_x, 16*mb_y); |
936 | 1080 s->me.skip=0; |
324 | 1081 |
320
cda7d0857baf
- ME setting moved to AVCodecContext/MpegEncContext, no longer a global.
pulento
parents:
304
diff
changeset
|
1082 switch(s->me_method) { |
0 | 1083 case ME_ZERO: |
1084 default: | |
1085 no_motion_search(s, &mx, &my); | |
455 | 1086 mx-= mb_x*16; |
1087 my-= mb_y*16; | |
0 | 1088 dmin = 0; |
1089 break; | |
1708 | 1090 #if 0 |
0 | 1091 case ME_FULL: |
1708 | 1092 dmin = full_motion_search(s, &mx, &my, range, ref_picture); |
455 | 1093 mx-= mb_x*16; |
1094 my-= mb_y*16; | |
0 | 1095 break; |
1096 case ME_LOG: | |
1708 | 1097 dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1098 mx-= mb_x*16; |
1099 my-= mb_y*16; | |
0 | 1100 break; |
1101 case ME_PHODS: | |
1708 | 1102 dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1103 mx-= mb_x*16; |
1104 my-= mb_y*16; | |
0 | 1105 break; |
1708 | 1106 #endif |
288 | 1107 case ME_X1: |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
1108 case ME_EPZS: |
288 | 1109 { |
294 | 1110 const int mot_stride = s->block_wrap[0]; |
1111 const int mot_xy = s->block_index[0]; | |
288 | 1112 |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1113 P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1114 P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; |
288 | 1115 |
1708 | 1116 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
280 | 1117 |
952 | 1118 if(mb_y) { |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1119 P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1120 P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1121 P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1122 P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1]; |
1708 | 1123 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift); |
1124 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
1125 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
280 | 1126 |
455 | 1127 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); |
1128 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1129 | |
1130 if(s->out_format == FMT_H263){ | |
1131 pred_x = P_MEDIAN[0]; | |
1132 pred_y = P_MEDIAN[1]; | |
1133 }else { /* mpeg1 at least */ | |
1134 pred_x= P_LEFT[0]; | |
1135 pred_y= P_LEFT[1]; | |
1136 } | |
952 | 1137 }else{ |
1138 pred_x= P_LEFT[0]; | |
1139 pred_y= P_LEFT[1]; | |
288 | 1140 } |
952 | 1141 |
280 | 1142 } |
1708 | 1143 dmin = s->me.motion_search[0](s, &mx, &my, P, pred_x, pred_y, |
1144 src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty); | |
281
1fc96b02142e
mpeg4 aspect_ratio_info in AVCodecContext (requested by alex)
michaelni
parents:
280
diff
changeset
|
1145 |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
1146 break; |
0 | 1147 } |
1148 | |
1149 /* intra / predictive decision */ | |
1150 xx = mb_x * 16; | |
1151 yy = mb_y * 16; | |
1152 | |
1708 | 1153 pix = src_data[0]; |
455 | 1154 /* At this point (mx,my) are full-pell and the relative displacement */ |
1708 | 1155 ppix = ref_data[0] + (my * s->linesize) + mx; |
289
648e9245546d
seems the old intra/inter decission is slightly better with a threshold, than the new one
michaelni
parents:
288
diff
changeset
|
1156 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1157 sum = s->dsp.pix_sum(pix, s->linesize); |
455 | 1158 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1159 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; |
1708 | 1160 vard = (s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16)+128)>>8; |
608 | 1161 |
455 | 1162 //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1163 pic->mb_var [s->mb_stride * mb_y + mb_x] = varc; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1164 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1165 pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1166 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; |
903 | 1167 pic->mb_var_sum += varc; |
1168 pic->mc_mb_var_sum += vard; | |
455 | 1169 //printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); |
320
cda7d0857baf
- ME setting moved to AVCodecContext/MpegEncContext, no longer a global.
pulento
parents:
304
diff
changeset
|
1170 |
0 | 1171 #if 0 |
233
3f5b72726118
- More work on preliminary bit rate control, just to be able to get an
pulento
parents:
232
diff
changeset
|
1172 printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", |
3f5b72726118
- More work on preliminary bit rate control, just to be able to get an
pulento
parents:
232
diff
changeset
|
1173 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); |
0 | 1174 #endif |
1389 | 1175 if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
608 | 1176 if (vard <= 64 || vard < varc) |
1177 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); | |
1178 else | |
913 | 1179 s->scene_change_score+= s->qscale; |
608 | 1180 |
294 | 1181 if (vard*2 + 200 > varc) |
1708 | 1182 mb_type|= CANDIDATE_MB_TYPE_INTRA; |
294 | 1183 if (varc*2 + 200 > vard){ |
1708 | 1184 mb_type|= CANDIDATE_MB_TYPE_INTER; |
1185 s->me.sub_motion_search(s, &mx, &my, dmin, | |
1186 pred_x, pred_y, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1494
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
1187 if(s->flags&CODEC_FLAG_MV0) |
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
1188 if(mx || my) |
1708 | 1189 mb_type |= CANDIDATE_MB_TYPE_SKIPED; //FIXME check difference |
304 | 1190 }else{ |
936 | 1191 mx <<=shift; |
1192 my <<=shift; | |
0 | 1193 } |
455 | 1194 if((s->flags&CODEC_FLAG_4MV) |
936 | 1195 && !s->me.skip && varc>50 && vard>10){ |
1708 | 1196 if(h263_mv4_search(s, mx, my, shift) < INT_MAX) |
1197 mb_type|=CANDIDATE_MB_TYPE_INTER4V; | |
455 | 1198 |
1199 set_p_mv_tables(s, mx, my, 0); | |
1200 }else | |
1201 set_p_mv_tables(s, mx, my, 1); | |
1708 | 1202 if((s->flags&CODEC_FLAG_INTERLACED_ME) |
1203 && !s->me.skip){ //FIXME varc/d checks | |
1204 if(interlaced_search(s, src_data, ref_data, s->p_field_mv_table, s->p_field_select_table, s->f_code, mx, my) < INT_MAX) | |
1205 mb_type |= CANDIDATE_MB_TYPE_INTER_I; | |
1206 } | |
294 | 1207 }else{ |
1633 | 1208 int intra_score, i; |
1708 | 1209 mb_type= CANDIDATE_MB_TYPE_INTER; |
1013 | 1210 |
1708 | 1211 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, |
1212 pred_x, pred_y, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1213 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) |
1708 | 1214 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, src_data, ref_data, stride, uvstride, mv_penalty); |
1013 | 1215 |
1216 if((s->flags&CODEC_FLAG_4MV) | |
1217 && !s->me.skip && varc>50 && vard>10){ | |
1708 | 1218 int dmin4= h263_mv4_search(s, mx, my, shift); |
1013 | 1219 if(dmin4 < dmin){ |
1708 | 1220 mb_type= CANDIDATE_MB_TYPE_INTER4V; |
1013 | 1221 dmin=dmin4; |
1222 } | |
1223 } | |
1708 | 1224 if((s->flags&CODEC_FLAG_INTERLACED_ME) |
1225 && !s->me.skip){ //FIXME varc/d checks | |
1226 int dmin_i= interlaced_search(s, src_data, ref_data, s->p_field_mv_table, s->p_field_select_table, s->f_code, mx, my); | |
1227 if(dmin_i < dmin){ | |
1228 mb_type = CANDIDATE_MB_TYPE_INTER_I; | |
1229 dmin= dmin_i; | |
1230 } | |
1231 } | |
1633 | 1232 |
1233 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; | |
1708 | 1234 set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V); |
1633 | 1235 |
1236 /* get intra luma score */ | |
1237 if((s->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ | |
1238 intra_score= (varc<<8) - 500; //FIXME dont scale it down so we dont have to fix it | |
1239 }else{ | |
1240 int mean= (sum+128)>>8; | |
1241 mean*= 0x01010101; | |
1242 | |
1243 for(i=0; i<16; i++){ | |
1244 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 0]) = mean; | |
1245 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 4]) = mean; | |
1246 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 8]) = mean; | |
1247 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+12]) = mean; | |
1248 } | |
1249 | |
1708 | 1250 intra_score= s->dsp.mb_cmp[0](s, s->me.scratchpad, pix, s->linesize, 16); |
1633 | 1251 } |
1252 #if 0 //FIXME | |
1253 /* get chroma score */ | |
1254 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
1255 for(i=1; i<3; i++){ | |
1256 uint8_t *dest_c; | |
1257 int mean; | |
1258 | |
1259 if(s->out_format == FMT_H263){ | |
1260 mean= (s->dc_val[i][mb_x + (mb_y+1)*(s->mb_width+2)] + 4)>>3; //FIXME not exact but simple ;) | |
1261 }else{ | |
1262 mean= (s->last_dc[i] + 4)>>3; | |
1263 } | |
1264 dest_c = s->new_picture.data[i] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |
1265 | |
1266 mean*= 0x01010101; | |
1267 for(i=0; i<8; i++){ | |
1268 *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 0]) = mean; | |
1269 *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 4]) = mean; | |
1270 } | |
1271 | |
1272 intra_score+= s->dsp.mb_cmp[1](s, s->me.scratchpad, dest_c, s->uvlinesize); | |
1273 } | |
1274 } | |
1275 #endif | |
1276 intra_score += s->me.mb_penalty_factor*16; | |
1013 | 1277 |
1633 | 1278 if(intra_score < dmin){ |
1708 | 1279 mb_type= CANDIDATE_MB_TYPE_INTRA; |
1280 s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup | |
1633 | 1281 }else |
1282 s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= 0; | |
1283 | |
1284 if (vard <= 64 || vard < varc) { //FIXME | |
608 | 1285 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
294 | 1286 }else{ |
1011 | 1287 s->scene_change_score+= s->qscale; |
294 | 1288 } |
1289 } | |
284 | 1290 |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1291 s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type; |
0 | 1292 } |
1293 | |
951 | 1294 int ff_pre_estimate_p_frame_motion(MpegEncContext * s, |
1295 int mb_x, int mb_y) | |
1296 { | |
1708 | 1297 int mx, my, dmin; |
951 | 1298 int pred_x=0, pred_y=0; |
1299 int P[10][2]; | |
1300 const int shift= 1+s->quarter_sample; | |
1162 | 1301 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1302 const int xy= mb_x + mb_y*s->mb_stride; |
1708 | 1303 const int stride= s->linesize; |
1304 const int uvstride= s->uvlinesize; | |
1305 uint8_t *src_data[3]= { | |
1306 s->new_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1307 s->new_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1308 s->new_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1309 }; | |
1310 uint8_t *ref_data[3]= { | |
1311 s->last_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1312 s->last_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1313 s->last_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1314 }; | |
951 | 1315 |
1316 assert(s->quarter_sample==0 || s->quarter_sample==1); | |
1317 | |
954 | 1318 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp); |
951 | 1319 |
1708 | 1320 get_limits(s, 16*mb_x, 16*mb_y); |
951 | 1321 s->me.skip=0; |
1322 | |
1323 P_LEFT[0] = s->p_mv_table[xy + 1][0]; | |
1324 P_LEFT[1] = s->p_mv_table[xy + 1][1]; | |
1325 | |
1708 | 1326 if(P_LEFT[0] < (s->me.xmin<<shift)) P_LEFT[0] = (s->me.xmin<<shift); |
951 | 1327 |
1328 /* special case for first line */ | |
1329 if (mb_y == s->mb_height-1) { | |
1330 pred_x= P_LEFT[0]; | |
1331 pred_y= P_LEFT[1]; | |
952 | 1332 P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]= |
1333 P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME | |
951 | 1334 } else { |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1335 P_TOP[0] = s->p_mv_table[xy + s->mb_stride ][0]; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1336 P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1]; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1337 P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0]; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1338 P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1]; |
1708 | 1339 if(P_TOP[1] < (s->me.ymin<<shift)) P_TOP[1] = (s->me.ymin<<shift); |
1340 if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift); | |
1341 if(P_TOPRIGHT[1] < (s->me.ymin<<shift)) P_TOPRIGHT[1]= (s->me.ymin<<shift); | |
951 | 1342 |
1343 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
1344 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1345 | |
952 | 1346 pred_x = P_MEDIAN[0]; |
1347 pred_y = P_MEDIAN[1]; | |
951 | 1348 } |
1708 | 1349 dmin = s->me.pre_motion_search(s, &mx, &my, P, pred_x, pred_y, |
1350 src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty); | |
952 | 1351 |
951 | 1352 s->p_mv_table[xy][0] = mx<<shift; |
1353 s->p_mv_table[xy][1] = my<<shift; | |
1354 | |
1355 return dmin; | |
1356 } | |
1357 | |
1057 | 1358 static int ff_estimate_motion_b(MpegEncContext * s, |
1708 | 1359 int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *src_data[3], |
1360 uint8_t *ref_data[3], int stride, int uvstride, int f_code) | |
0 | 1361 { |
1708 | 1362 int mx, my, dmin; |
324 | 1363 int pred_x=0, pred_y=0; |
455 | 1364 int P[10][2]; |
324 | 1365 const int shift= 1+s->quarter_sample; |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1366 const int mot_stride = s->mb_stride; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1367 const int mot_xy = mb_y*mot_stride + mb_x; |
1708 | 1368 uint8_t * const ref_picture= ref_data[0] - 16*s->mb_x - 16*s->mb_y*s->linesize; //FIXME ugly |
1162 | 1369 uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; |
948 | 1370 int mv_scale; |
936 | 1371 |
1372 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | |
1373 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | |
1013 | 1374 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
936 | 1375 |
1708 | 1376 get_limits(s, 16*mb_x, 16*mb_y); |
324 | 1377 |
1378 switch(s->me_method) { | |
1379 case ME_ZERO: | |
1380 default: | |
1381 no_motion_search(s, &mx, &my); | |
1382 dmin = 0; | |
455 | 1383 mx-= mb_x*16; |
1384 my-= mb_y*16; | |
324 | 1385 break; |
1708 | 1386 #if 0 |
324 | 1387 case ME_FULL: |
1708 | 1388 dmin = full_motion_search(s, &mx, &my, range, ref_picture); |
455 | 1389 mx-= mb_x*16; |
1390 my-= mb_y*16; | |
324 | 1391 break; |
1392 case ME_LOG: | |
1708 | 1393 dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1394 mx-= mb_x*16; |
1395 my-= mb_y*16; | |
324 | 1396 break; |
1397 case ME_PHODS: | |
1708 | 1398 dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1399 mx-= mb_x*16; |
1400 my-= mb_y*16; | |
324 | 1401 break; |
1708 | 1402 #endif |
324 | 1403 case ME_X1: |
1404 case ME_EPZS: | |
1405 { | |
455 | 1406 P_LEFT[0] = mv_table[mot_xy - 1][0]; |
1407 P_LEFT[1] = mv_table[mot_xy - 1][1]; | |
324 | 1408 |
1708 | 1409 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
324 | 1410 |
1411 /* special case for first line */ | |
952 | 1412 if (mb_y) { |
455 | 1413 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; |
1414 P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; | |
1415 P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1 ][0]; | |
1416 P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1 ][1]; | |
1708 | 1417 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1]= (s->me.ymax<<shift); |
1418 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
1419 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
324 | 1420 |
455 | 1421 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); |
1422 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
324 | 1423 } |
455 | 1424 pred_x= P_LEFT[0]; |
1425 pred_y= P_LEFT[1]; | |
324 | 1426 } |
948 | 1427 |
1428 if(mv_table == s->b_forw_mv_table){ | |
1429 mv_scale= (s->pb_time<<16) / (s->pp_time<<shift); | |
1430 }else{ | |
1431 mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift); | |
1432 } | |
1433 | |
1708 | 1434 dmin = s->me.motion_search[0](s, &mx, &my, P, pred_x, pred_y, |
1435 src_data, ref_data, stride, uvstride, s->p_mv_table, mv_scale, mv_penalty); | |
324 | 1436 |
1437 break; | |
1438 } | |
1439 | |
1708 | 1440 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, |
1441 pred_x, pred_y, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1442 |
1443 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1444 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, src_data, ref_data, stride, uvstride, mv_penalty); |
1013 | 1445 |
455 | 1446 //printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my); |
324 | 1447 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; |
1448 mv_table[mot_xy][0]= mx; | |
1449 mv_table[mot_xy][1]= my; | |
936 | 1450 |
327 | 1451 return dmin; |
324 | 1452 } |
1453 | |
1708 | 1454 static inline int check_bidir_mv(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1455 int stride, int uvstride, | |
327 | 1456 int motion_fx, int motion_fy, |
1457 int motion_bx, int motion_by, | |
1458 int pred_fx, int pred_fy, | |
1708 | 1459 int pred_bx, int pred_by, |
1460 int size, int h) | |
327 | 1461 { |
1462 //FIXME optimize? | |
936 | 1463 //FIXME move into template? |
1464 //FIXME better f_code prediction (max mv & distance) | |
1708 | 1465 //FIXME pointers |
1162 | 1466 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame |
936 | 1467 uint8_t *dest_y = s->me.scratchpad; |
327 | 1468 uint8_t *ptr; |
1469 int dxy; | |
1470 int src_x, src_y; | |
1471 int fbmin; | |
1472 | |
936 | 1473 if(s->quarter_sample){ |
1474 dxy = ((motion_fy & 3) << 2) | (motion_fx & 3); | |
1708 | 1475 src_x = motion_fx >> 2; |
1476 src_y = motion_fy >> 2; | |
327 | 1477 |
1708 | 1478 ptr = ref_data[0] + (src_y * stride) + src_x; |
1479 s->dsp.put_qpel_pixels_tab[0][dxy](dest_y , ptr , stride); | |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1480 |
936 | 1481 dxy = ((motion_by & 3) << 2) | (motion_bx & 3); |
1708 | 1482 src_x = motion_bx >> 2; |
1483 src_y = motion_by >> 2; | |
936 | 1484 |
1708 | 1485 ptr = ref_data[3] + (src_y * stride) + src_x; |
1486 s->dsp.avg_qpel_pixels_tab[size][dxy](dest_y , ptr , stride); | |
936 | 1487 }else{ |
1488 dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); | |
1708 | 1489 src_x = motion_fx >> 1; |
1490 src_y = motion_fy >> 1; | |
327 | 1491 |
1708 | 1492 ptr = ref_data[0] + (src_y * stride) + src_x; |
1493 s->dsp.put_pixels_tab[size][dxy](dest_y , ptr , stride, h); | |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1494 |
936 | 1495 dxy = ((motion_by & 1) << 1) | (motion_bx & 1); |
1708 | 1496 src_x = motion_bx >> 1; |
1497 src_y = motion_by >> 1; | |
936 | 1498 |
1708 | 1499 ptr = ref_data[3] + (src_y * stride) + src_x; |
1500 s->dsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h); | |
936 | 1501 } |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1502 |
1013 | 1503 fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.mb_penalty_factor |
1504 +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.mb_penalty_factor | |
1708 | 1505 + s->dsp.mb_cmp[size](s, src_data[0], dest_y, stride, h); //FIXME new_pic |
1013 | 1506 |
1507 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
1508 } | |
1509 //FIXME CHROMA !!! | |
1510 | |
327 | 1511 return fbmin; |
1512 } | |
1513 | |
1514 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ | |
1708 | 1515 static inline int bidir_refine(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1516 int stride, int uvstride, | |
327 | 1517 int mb_x, int mb_y) |
1518 { | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1519 const int mot_stride = s->mb_stride; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1520 const int xy = mb_y *mot_stride + mb_x; |
327 | 1521 int fbmin; |
1522 int pred_fx= s->b_bidir_forw_mv_table[xy-1][0]; | |
1523 int pred_fy= s->b_bidir_forw_mv_table[xy-1][1]; | |
1524 int pred_bx= s->b_bidir_back_mv_table[xy-1][0]; | |
1525 int pred_by= s->b_bidir_back_mv_table[xy-1][1]; | |
1526 int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; | |
1527 int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; | |
1528 int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; | |
1529 int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; | |
1530 | |
1531 //FIXME do refinement and add flag | |
1532 | |
1708 | 1533 fbmin= check_bidir_mv(s, src_data, ref_data, stride, uvstride, |
327 | 1534 motion_fx, motion_fy, |
1535 motion_bx, motion_by, | |
1536 pred_fx, pred_fy, | |
1708 | 1537 pred_bx, pred_by, |
1538 0, 16); | |
327 | 1539 |
1540 return fbmin; | |
1541 } | |
1542 | |
1708 | 1543 static inline int direct_search(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1544 int stride, int uvstride, | |
327 | 1545 int mb_x, int mb_y) |
324 | 1546 { |
455 | 1547 int P[10][2]; |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1548 const int mot_stride = s->mb_stride; |
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1549 const int mot_xy = mb_y*mot_stride + mb_x; |
936 | 1550 const int shift= 1+s->quarter_sample; |
1551 int dmin, i; | |
327 | 1552 const int time_pp= s->pp_time; |
664 | 1553 const int time_pb= s->pb_time; |
936 | 1554 int mx, my, xmin, xmax, ymin, ymax; |
327 | 1555 int16_t (*mv_table)[2]= s->b_direct_mv_table; |
1162 | 1556 uint8_t * const mv_penalty= s->me.mv_penalty[1] + MAX_MV; |
936 | 1557 |
1558 ymin= xmin=(-32)>>shift; | |
1559 ymax= xmax= 31>>shift; | |
1560 | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1561 if(IS_8X8(s->next_picture.mb_type[mot_xy])){ |
936 | 1562 s->mv_type= MV_TYPE_8X8; |
1563 }else{ | |
1564 s->mv_type= MV_TYPE_16X16; | |
327 | 1565 } |
936 | 1566 |
1567 for(i=0; i<4; i++){ | |
1568 int index= s->block_index[i]; | |
1569 int min, max; | |
1570 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1571 s->me.co_located_mv[i][0]= s->next_picture.motion_val[0][index][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1572 s->me.co_located_mv[i][1]= s->next_picture.motion_val[0][index][1]; |
936 | 1573 s->me.direct_basis_mv[i][0]= s->me.co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); |
1574 s->me.direct_basis_mv[i][1]= s->me.co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); | |
1575 // s->me.direct_basis_mv[1][i][0]= s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3); | |
1576 // s->me.direct_basis_mv[1][i][1]= s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3); | |
1577 | |
1578 max= FFMAX(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift; | |
1579 min= FFMIN(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift; | |
1050 | 1580 max+= (2*mb_x + (i& 1))*8 + 1; // +-1 is for the simpler rounding |
1581 min+= (2*mb_x + (i& 1))*8 - 1; | |
960 | 1582 xmax= FFMIN(xmax, s->width - max); |
1583 xmin= FFMAX(xmin, - 16 - min); | |
936 | 1584 |
1585 max= FFMAX(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift; | |
1586 min= FFMIN(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift; | |
1050 | 1587 max+= (2*mb_y + (i>>1))*8 + 1; // +-1 is for the simpler rounding |
1588 min+= (2*mb_y + (i>>1))*8 - 1; | |
960 | 1589 ymax= FFMIN(ymax, s->height - max); |
1590 ymin= FFMAX(ymin, - 16 - min); | |
936 | 1591 |
1592 if(s->mv_type == MV_TYPE_16X16) break; | |
327 | 1593 } |
936 | 1594 |
1595 assert(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16); | |
1596 | |
1597 if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){ | |
1598 s->b_direct_mv_table[mot_xy][0]= 0; | |
1599 s->b_direct_mv_table[mot_xy][1]= 0; | |
1600 | |
1601 return 256*256*256*64; | |
1602 } | |
1708 | 1603 |
1604 s->me.xmin= xmin; | |
1605 s->me.ymin= ymin; | |
1606 s->me.xmax= xmax; | |
1607 s->me.ymax= ymax; | |
936 | 1608 |
950 | 1609 P_LEFT[0] = clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift); |
1610 P_LEFT[1] = clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift); | |
1611 | |
1612 /* special case for first line */ | |
952 | 1613 if (mb_y) { |
950 | 1614 P_TOP[0] = clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift); |
1615 P_TOP[1] = clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift); | |
1616 P_TOPRIGHT[0] = clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift); | |
1617 P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift); | |
1618 | |
1619 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
1620 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1621 } | |
1013 | 1622 |
1623 //FIXME direct_search ptr in context!!! (needed for chroma anyway or this will get messy) | |
936 | 1624 if(s->flags&CODEC_FLAG_QPEL){ |
1708 | 1625 dmin = simple_direct_qpel_epzs_motion_search(s, &mx, &my, P, 0, 0, |
1626 src_data, ref_data, stride, uvstride, mv_table, 1<<14, mv_penalty); | |
1627 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, | |
1628 0, 0, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1629 |
1630 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1631 dmin= simple_direct_qpel_qpel_get_mb_score(s, mx, my, 0, 0, src_data, ref_data, stride, uvstride, mv_penalty); |
936 | 1632 }else{ |
1708 | 1633 dmin = simple_direct_hpel_epzs_motion_search(s, &mx, &my, P, 0, 0, |
1634 src_data, ref_data, stride, uvstride, mv_table, 1<<15, mv_penalty); | |
1635 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, | |
1636 0, 0, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1637 |
1638 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1639 dmin= simple_direct_hpel_hpel_get_mb_score(s, mx, my, 0, 0, src_data, ref_data, stride, uvstride, mv_penalty); |
327 | 1640 } |
1708 | 1641 |
1642 get_limits(s, 16*mb_x, 16*mb_y); //restore s->me.?min/max, maybe not needed | |
327 | 1643 |
1644 s->b_direct_mv_table[mot_xy][0]= mx; | |
1645 s->b_direct_mv_table[mot_xy][1]= my; | |
1646 return dmin; | |
324 | 1647 } |
1648 | |
1649 void ff_estimate_b_frame_motion(MpegEncContext * s, | |
1650 int mb_x, int mb_y) | |
1651 { | |
1013 | 1652 const int penalty_factor= s->me.mb_penalty_factor; |
1708 | 1653 int fmin, bmin, dmin, fbmin, bimin, fimin; |
327 | 1654 int type=0; |
1708 | 1655 const int stride= s->linesize; |
1656 const int uvstride= s->uvlinesize; | |
1657 uint8_t *src_data[3]= { | |
1658 s->new_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1659 s->new_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1660 s->new_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y) | |
1661 }; | |
1662 uint8_t *ref_data[6]= { | |
1663 s->last_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1664 s->last_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1665 s->last_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y), | |
1666 s->next_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1667 s->next_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1668 s->next_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y) | |
1669 }; | |
327 | 1670 |
1426 | 1671 s->me.skip=0; |
1672 if (s->codec_id == CODEC_ID_MPEG4) | |
1708 | 1673 dmin= direct_search(s, src_data, ref_data, stride, uvstride, mb_x, mb_y); |
1426 | 1674 else |
1675 dmin= INT_MAX; | |
1708 | 1676 //FIXME penalty stuff for non mpeg4 |
1426 | 1677 s->me.skip=0; |
1708 | 1678 fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, src_data, |
1679 ref_data, stride, uvstride, s->f_code) + 3*penalty_factor; | |
1426 | 1680 |
1681 s->me.skip=0; | |
1708 | 1682 bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, src_data, |
1683 ref_data+3, stride, uvstride, s->b_code) + 2*penalty_factor; | |
324 | 1684 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); |
327 | 1685 |
1426 | 1686 s->me.skip=0; |
1708 | 1687 fbmin= bidir_refine(s, src_data, ref_data, stride, uvstride, mb_x, mb_y) + penalty_factor; |
1013 | 1688 //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); |
1708 | 1689 |
1690 if(s->flags & CODEC_FLAG_INTERLACED_ME){ | |
1691 const int xy = mb_y*s->mb_stride + mb_x; | |
1692 | |
1693 //FIXME mb type penalty | |
1694 s->me.skip=0; | |
1695 fimin= interlaced_search(s, src_data, ref_data , | |
1696 s->b_field_mv_table[0], s->b_field_select_table[0], s->f_code, | |
1697 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); | |
1698 bimin= interlaced_search(s, src_data, ref_data+3, | |
1699 s->b_field_mv_table[1], s->b_field_select_table[1], s->b_code, | |
1700 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1]); | |
1701 }else | |
1702 fimin= bimin= INT_MAX; | |
1703 | |
612 | 1704 { |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1705 int score= fmin; |
1708 | 1706 type = CANDIDATE_MB_TYPE_FORWARD; |
327 | 1707 |
1426 | 1708 if (dmin <= score){ |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1709 score = dmin; |
1708 | 1710 type = CANDIDATE_MB_TYPE_DIRECT; |
327 | 1711 } |
1712 if(bmin<score){ | |
1713 score=bmin; | |
1708 | 1714 type= CANDIDATE_MB_TYPE_BACKWARD; |
327 | 1715 } |
1716 if(fbmin<score){ | |
1717 score=fbmin; | |
1708 | 1718 type= CANDIDATE_MB_TYPE_BIDIR; |
1719 } | |
1720 if(fimin<score){ | |
1721 score=fimin; | |
1722 type= CANDIDATE_MB_TYPE_FORWARD_I; | |
1723 } | |
1724 if(bimin<score){ | |
1725 score=bimin; | |
1726 type= CANDIDATE_MB_TYPE_BACKWARD_I; | |
327 | 1727 } |
1013 | 1728 |
807
0e1d375c537f
fixing q>0.0 assert failure caused by overflow of variance for b frames
michaelni
parents:
765
diff
changeset
|
1729 score= ((unsigned)(score*score + 128*256))>>16; |
903 | 1730 s->current_picture.mc_mb_var_sum += score; |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1731 s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE |
327 | 1732 } |
612 | 1733 |
1389 | 1734 if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
1708 | 1735 type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT; |
1736 if(fimin < INT_MAX) | |
1737 type |= CANDIDATE_MB_TYPE_FORWARD_I; | |
1738 if(bimin < INT_MAX) | |
1739 type |= CANDIDATE_MB_TYPE_BACKWARD_I; | |
1740 if(fimin < INT_MAX && bimin < INT_MAX){ | |
1741 type |= CANDIDATE_MB_TYPE_BIDIR_I; | |
1742 } | |
1743 //FIXME something smarter | |
1744 if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB | |
1729 | 1745 #if 0 |
1746 if(s->out_format == FMT_MPEG1) | |
1747 type |= CANDIDATE_MB_TYPE_INTRA; | |
1748 #endif | |
612 | 1749 } |
1750 | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1751 s->mb_type[mb_y*s->mb_stride + mb_x]= type; |
324 | 1752 } |
0 | 1753 |
324 | 1754 /* find best f_code for ME which do unlimited searches */ |
1755 int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) | |
1756 { | |
1757 if(s->me_method>=ME_EPZS){ | |
455 | 1758 int score[8]; |
324 | 1759 int i, y; |
1064 | 1760 uint8_t * fcode_tab= s->fcode_tab; |
455 | 1761 int best_fcode=-1; |
1762 int best_score=-10000000; | |
324 | 1763 |
936 | 1764 for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); |
324 | 1765 |
1766 for(y=0; y<s->mb_height; y++){ | |
1767 int x; | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1768 int xy= y*s->mb_stride; |
324 | 1769 for(x=0; x<s->mb_width; x++){ |
1634 | 1770 if(s->mb_type[xy] & type){ |
847 | 1771 int fcode= FFMAX(fcode_tab[mv_table[xy][0] + MAX_MV], |
1772 fcode_tab[mv_table[xy][1] + MAX_MV]); | |
455 | 1773 int j; |
1774 | |
1775 for(j=0; j<fcode && j<8; j++){ | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1776 if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) |
455 | 1777 score[j]-= 170; |
1778 } | |
324 | 1779 } |
1780 xy++; | |
1781 } | |
1782 } | |
455 | 1783 |
1784 for(i=1; i<8; i++){ | |
1785 if(score[i] > best_score){ | |
1786 best_score= score[i]; | |
1787 best_fcode= i; | |
1788 } | |
1789 // printf("%d %d\n", i, score[i]); | |
1790 } | |
327 | 1791 |
324 | 1792 // printf("fcode: %d type: %d\n", i, s->pict_type); |
455 | 1793 return best_fcode; |
324 | 1794 /* for(i=0; i<=MAX_FCODE; i++){ |
1795 printf("%d ", mv_num[i]); | |
1796 } | |
1797 printf("\n");*/ | |
1798 }else{ | |
1799 return 1; | |
0 | 1800 } |
1801 } | |
1802 | |
324 | 1803 void ff_fix_long_p_mvs(MpegEncContext * s) |
1804 { | |
1805 const int f_code= s->f_code; | |
1086 | 1806 int y, range; |
1421 | 1807 assert(s->pict_type==P_TYPE); |
1086 | 1808 |
1421 | 1809 range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); |
1086 | 1810 |
1811 if(s->msmpeg4_version) range= 16; | |
1812 | |
1813 if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range; | |
1814 | |
455 | 1815 //printf("%d no:%d %d//\n", clip, noclip, f_code); |
324 | 1816 if(s->flags&CODEC_FLAG_4MV){ |
1817 const int wrap= 2+ s->mb_width*2; | |
1818 | |
1819 /* clip / convert to intra 8x8 type MVs */ | |
1820 for(y=0; y<s->mb_height; y++){ | |
1821 int xy= (y*2 + 1)*wrap + 1; | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1822 int i= y*s->mb_stride; |
324 | 1823 int x; |
1824 | |
1825 for(x=0; x<s->mb_width; x++){ | |
1708 | 1826 if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){ |
324 | 1827 int block; |
1828 for(block=0; block<4; block++){ | |
1829 int off= (block& 1) + (block>>1)*wrap; | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1830 int mx= s->current_picture.motion_val[0][ xy + off ][0]; |
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1831 int my= s->current_picture.motion_val[0][ xy + off ][1]; |
324 | 1832 |
1086 | 1833 if( mx >=range || mx <-range |
1834 || my >=range || my <-range){ | |
1708 | 1835 s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V; |
1836 s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA; | |
1837 s->current_picture.mb_type[i]= CANDIDATE_MB_TYPE_INTRA; | |
324 | 1838 } |
1839 } | |
1840 } | |
502 | 1841 xy+=2; |
1842 i++; | |
324 | 1843 } |
1844 } | |
1845 } | |
1846 } | |
1847 | |
1708 | 1848 /** |
1849 * | |
1850 * @param truncate 1 for truncation, 0 for using intra | |
1851 */ | |
1852 void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, | |
1853 int16_t (*mv_table)[2], int f_code, int type, int truncate) | |
324 | 1854 { |
1708 | 1855 int y, h_range, v_range; |
324 | 1856 |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1857 // RAL: 8 in MPEG-1, 16 in MPEG-4 |
1421 | 1858 int range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); |
1708 | 1859 |
1860 if(s->msmpeg4_version) range= 16; | |
1086 | 1861 if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range; |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1862 |
1708 | 1863 h_range= range; |
1864 v_range= field_select_table ? range>>1 : range; | |
1865 | |
324 | 1866 /* clip / convert to intra 16x16 type MVs */ |
1867 for(y=0; y<s->mb_height; y++){ | |
1868 int x; | |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1869 int xy= y*s->mb_stride; |
1086 | 1870 for(x=0; x<s->mb_width; x++){ |
1177
fea03d2c4946
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
michaelni
parents:
1162
diff
changeset
|
1871 if (s->mb_type[xy] & type){ // RAL: "type" test added... |
1708 | 1872 if(field_select_table==NULL || field_select_table[xy] == field_select){ |
1873 if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range | |
1874 || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){ | |
1086 | 1875 |
1708 | 1876 if(truncate){ |
1877 if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1; | |
1878 else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range; | |
1879 if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1; | |
1880 else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range; | |
1881 }else{ | |
1882 s->mb_type[xy] &= ~type; | |
1883 s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA; | |
1884 mv_table[xy][0]= | |
1885 mv_table[xy][1]= 0; | |
1886 } | |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1887 } |
1086 | 1888 } |
324 | 1889 } |
1890 xy++; | |
1891 } | |
1892 } | |
1893 } |