Mercurial > libavcodec.hg
annotate motion_est.c @ 1708:dea5b2946999 libavcodec
interlaced motion estimation
interlaced mpeg2 encoding
P & B frames
rate distored interlaced mb decission
alternate scantable support
4mv encoding fixes (thats also why the regression tests change)
passing height to most dsp functions
interlaced mpeg4 encoding (no direct mode MBs yet)
various related cleanups
disabled old motion estimaton algorithms (log, full, ...) they will either be fixed or removed
author | michael |
---|---|
date | Tue, 30 Dec 2003 16:07:57 +0000 |
parents | 30746f429df6 |
children | a4a5e7521339 |
rev | line source |
---|---|
0 | 1 /* |
2 * Motion estimation | |
429 | 3 * Copyright (c) 2000,2001 Fabrice Bellard. |
1011 | 4 * Copyright (c) 2002-2003 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 | |
1708 | 281 static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ |
936 | 282 return 0; |
283 } | |
284 | |
285 static void set_cmp(MpegEncContext *s, me_cmp_func *cmp, int type){ | |
286 DSPContext* c= &s->dsp; | |
287 int i; | |
288 | |
1708 | 289 memset(cmp, 0, sizeof(void*)*5); |
290 | |
291 for(i=0; i<4; i++){ | |
292 switch(type&0xFF){ | |
293 case FF_CMP_SAD: | |
294 cmp[i]= c->sad[i]; | |
295 break; | |
296 case FF_CMP_SATD: | |
297 cmp[i]= c->hadamard8_diff[i]; | |
298 break; | |
299 case FF_CMP_SSE: | |
300 cmp[i]= c->sse[i]; | |
301 break; | |
302 case FF_CMP_DCT: | |
303 cmp[i]= c->dct_sad[i]; | |
304 break; | |
305 case FF_CMP_PSNR: | |
306 cmp[i]= c->quant_psnr[i]; | |
307 break; | |
308 case FF_CMP_BIT: | |
309 cmp[i]= c->bit[i]; | |
310 break; | |
311 case FF_CMP_RD: | |
312 cmp[i]= c->rd[i]; | |
313 break; | |
314 case FF_CMP_ZERO: | |
936 | 315 cmp[i]= zero_cmp; |
1708 | 316 break; |
317 default: | |
318 av_log(s->avctx, AV_LOG_ERROR,"internal error in cmp function selection\n"); | |
936 | 319 } |
320 } | |
1014
48349e11c9b2
C99 initializers and kill warnings patch by (mru at users dot sourceforge dot net (M¸«©ns Rullg¸«©rd))
michaelni
parents:
1013
diff
changeset
|
321 } |
936 | 322 |
323 static inline int get_penalty_factor(MpegEncContext *s, int type){ | |
1013 | 324 switch(type&0xFF){ |
936 | 325 default: |
326 case FF_CMP_SAD: | |
1013 | 327 return s->qscale*2; |
936 | 328 case FF_CMP_DCT: |
1013 | 329 return s->qscale*3; |
936 | 330 case FF_CMP_SATD: |
1013 | 331 return s->qscale*6; |
1007 | 332 case FF_CMP_SSE: |
1013 | 333 return s->qscale*s->qscale*2; |
1007 | 334 case FF_CMP_BIT: |
335 return 1; | |
336 case FF_CMP_RD: | |
1013 | 337 case FF_CMP_PSNR: |
338 return (s->qscale*s->qscale*185 + 64)>>7; | |
936 | 339 } |
340 } | |
341 | |
342 void ff_init_me(MpegEncContext *s){ | |
954 | 343 set_cmp(s, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp); |
936 | 344 set_cmp(s, s->dsp.me_cmp, s->avctx->me_cmp); |
345 set_cmp(s, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); | |
346 set_cmp(s, s->dsp.mb_cmp, s->avctx->mb_cmp); | |
347 | |
348 if(s->flags&CODEC_FLAG_QPEL){ | |
349 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) | |
350 s->me.sub_motion_search= simple_chroma_qpel_motion_search; | |
351 else | |
352 s->me.sub_motion_search= simple_qpel_motion_search; | |
353 }else{ | |
354 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) | |
355 s->me.sub_motion_search= simple_chroma_hpel_motion_search; | |
1013 | 356 else if( s->avctx->me_sub_cmp == FF_CMP_SAD |
357 && s->avctx-> me_cmp == FF_CMP_SAD | |
358 && s->avctx-> mb_cmp == FF_CMP_SAD) | |
1708 | 359 s->me.sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles |
936 | 360 else |
361 s->me.sub_motion_search= simple_hpel_motion_search; | |
362 } | |
363 | |
364 if(s->avctx->me_cmp&FF_CMP_CHROMA){ | |
365 s->me.motion_search[0]= simple_chroma_epzs_motion_search; | |
366 s->me.motion_search[1]= simple_chroma_epzs_motion_search4; | |
1708 | 367 s->me.motion_search[4]= simple_chroma_epzs_motion_search2; |
936 | 368 }else{ |
369 s->me.motion_search[0]= simple_epzs_motion_search; | |
370 s->me.motion_search[1]= simple_epzs_motion_search4; | |
1708 | 371 s->me.motion_search[4]= simple_epzs_motion_search2; |
936 | 372 } |
954 | 373 |
374 if(s->avctx->me_pre_cmp&FF_CMP_CHROMA){ | |
375 s->me.pre_motion_search= simple_chroma_epzs_motion_search; | |
376 }else{ | |
377 s->me.pre_motion_search= simple_epzs_motion_search; | |
378 } | |
1013 | 379 |
380 if(s->flags&CODEC_FLAG_QPEL){ | |
381 if(s->avctx->mb_cmp&FF_CMP_CHROMA) | |
382 s->me.get_mb_score= simple_chroma_qpel_get_mb_score; | |
383 else | |
384 s->me.get_mb_score= simple_qpel_get_mb_score; | |
385 }else{ | |
386 if(s->avctx->mb_cmp&FF_CMP_CHROMA) | |
387 s->me.get_mb_score= simple_chroma_hpel_get_mb_score; | |
388 else | |
389 s->me.get_mb_score= simple_hpel_get_mb_score; | |
390 } | |
936 | 391 } |
392 | |
1419 | 393 #if 0 |
1064 | 394 static int pix_dev(uint8_t * pix, int line_size, int mean) |
284 | 395 { |
396 int s, i, j; | |
397 | |
398 s = 0; | |
399 for (i = 0; i < 16; i++) { | |
400 for (j = 0; j < 16; j += 8) { | |
401 s += ABS(pix[0]-mean); | |
402 s += ABS(pix[1]-mean); | |
403 s += ABS(pix[2]-mean); | |
404 s += ABS(pix[3]-mean); | |
405 s += ABS(pix[4]-mean); | |
406 s += ABS(pix[5]-mean); | |
407 s += ABS(pix[6]-mean); | |
408 s += ABS(pix[7]-mean); | |
409 pix += 8; | |
410 } | |
411 pix += line_size - 16; | |
412 } | |
413 return s; | |
414 } | |
1419 | 415 #endif |
284 | 416 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
417 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
|
418 int *mx_ptr, int *my_ptr) |
0 | 419 { |
420 *mx_ptr = 16 * s->mb_x; | |
421 *my_ptr = 16 * s->mb_y; | |
422 } | |
423 | |
424 static int full_motion_search(MpegEncContext * s, | |
425 int *mx_ptr, int *my_ptr, int range, | |
324 | 426 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 427 { |
428 int x1, y1, x2, y2, xx, yy, x, y; | |
429 int mx, my, dmin, d; | |
1064 | 430 uint8_t *pix; |
0 | 431 |
432 xx = 16 * s->mb_x; | |
433 yy = 16 * s->mb_y; | |
434 x1 = xx - range + 1; /* we loose one pixel to avoid boundary pb with half pixel pred */ | |
435 if (x1 < xmin) | |
436 x1 = xmin; | |
437 x2 = xx + range - 1; | |
438 if (x2 > xmax) | |
439 x2 = xmax; | |
440 y1 = yy - range + 1; | |
441 if (y1 < ymin) | |
442 y1 = ymin; | |
443 y2 = yy + range - 1; | |
444 if (y2 > ymax) | |
445 y2 = ymax; | |
903 | 446 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 447 dmin = 0x7fffffff; |
448 mx = 0; | |
449 my = 0; | |
450 for (y = y1; y <= y2; y++) { | |
451 for (x = x1; x <= x2; x++) { | |
1708 | 452 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, |
453 s->linesize, 16); | |
0 | 454 if (d < dmin || |
455 (d == dmin && | |
456 (abs(x - xx) + abs(y - yy)) < | |
457 (abs(mx - xx) + abs(my - yy)))) { | |
458 dmin = d; | |
459 mx = x; | |
460 my = y; | |
461 } | |
462 } | |
463 } | |
464 | |
465 *mx_ptr = mx; | |
466 *my_ptr = my; | |
467 | |
468 #if 0 | |
469 if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) || | |
470 *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) { | |
471 fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr); | |
472 } | |
473 #endif | |
474 return dmin; | |
475 } | |
476 | |
477 | |
478 static int log_motion_search(MpegEncContext * s, | |
479 int *mx_ptr, int *my_ptr, int range, | |
324 | 480 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 481 { |
482 int x1, y1, x2, y2, xx, yy, x, y; | |
483 int mx, my, dmin, d; | |
1064 | 484 uint8_t *pix; |
0 | 485 |
486 xx = s->mb_x << 4; | |
487 yy = s->mb_y << 4; | |
488 | |
489 /* Left limit */ | |
490 x1 = xx - range; | |
491 if (x1 < xmin) | |
492 x1 = xmin; | |
493 | |
494 /* Right limit */ | |
495 x2 = xx + range; | |
496 if (x2 > xmax) | |
497 x2 = xmax; | |
498 | |
499 /* Upper limit */ | |
500 y1 = yy - range; | |
501 if (y1 < ymin) | |
502 y1 = ymin; | |
503 | |
504 /* Lower limit */ | |
505 y2 = yy + range; | |
506 if (y2 > ymax) | |
507 y2 = ymax; | |
508 | |
903 | 509 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 510 dmin = 0x7fffffff; |
511 mx = 0; | |
512 my = 0; | |
513 | |
514 do { | |
515 for (y = y1; y <= y2; y += range) { | |
516 for (x = x1; x <= x2; x += range) { | |
1708 | 517 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 518 if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
519 dmin = d; | |
520 mx = x; | |
521 my = y; | |
522 } | |
523 } | |
524 } | |
525 | |
526 range = range >> 1; | |
527 | |
528 x1 = mx - range; | |
529 if (x1 < xmin) | |
530 x1 = xmin; | |
531 | |
532 x2 = mx + range; | |
533 if (x2 > xmax) | |
534 x2 = xmax; | |
535 | |
536 y1 = my - range; | |
537 if (y1 < ymin) | |
538 y1 = ymin; | |
539 | |
540 y2 = my + range; | |
541 if (y2 > ymax) | |
542 y2 = ymax; | |
543 | |
544 } while (range >= 1); | |
545 | |
546 #ifdef DEBUG | |
547 fprintf(stderr, "log - MX: %d\tMY: %d\n", mx, my); | |
548 #endif | |
549 *mx_ptr = mx; | |
550 *my_ptr = my; | |
551 return dmin; | |
552 } | |
553 | |
554 static int phods_motion_search(MpegEncContext * s, | |
555 int *mx_ptr, int *my_ptr, int range, | |
324 | 556 int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) |
0 | 557 { |
558 int x1, y1, x2, y2, xx, yy, x, y, lastx, d; | |
559 int mx, my, dminx, dminy; | |
1064 | 560 uint8_t *pix; |
0 | 561 |
562 xx = s->mb_x << 4; | |
563 yy = s->mb_y << 4; | |
564 | |
565 /* Left limit */ | |
566 x1 = xx - range; | |
567 if (x1 < xmin) | |
568 x1 = xmin; | |
569 | |
570 /* Right limit */ | |
571 x2 = xx + range; | |
572 if (x2 > xmax) | |
573 x2 = xmax; | |
574 | |
575 /* Upper limit */ | |
576 y1 = yy - range; | |
577 if (y1 < ymin) | |
578 y1 = ymin; | |
579 | |
580 /* Lower limit */ | |
581 y2 = yy + range; | |
582 if (y2 > ymax) | |
583 y2 = ymax; | |
584 | |
903 | 585 pix = s->new_picture.data[0] + (yy * s->linesize) + xx; |
0 | 586 mx = 0; |
587 my = 0; | |
588 | |
589 x = xx; | |
590 y = yy; | |
591 do { | |
592 dminx = 0x7fffffff; | |
593 dminy = 0x7fffffff; | |
594 | |
595 lastx = x; | |
596 for (x = x1; x <= x2; x += range) { | |
1708 | 597 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 598 if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
599 dminx = d; | |
600 mx = x; | |
601 } | |
602 } | |
603 | |
604 x = lastx; | |
605 for (y = y1; y <= y2; y += range) { | |
1708 | 606 d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); |
0 | 607 if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { |
608 dminy = d; | |
609 my = y; | |
610 } | |
611 } | |
612 | |
613 range = range >> 1; | |
614 | |
615 x = mx; | |
616 y = my; | |
617 x1 = mx - range; | |
618 if (x1 < xmin) | |
619 x1 = xmin; | |
620 | |
621 x2 = mx + range; | |
622 if (x2 > xmax) | |
623 x2 = xmax; | |
624 | |
625 y1 = my - range; | |
626 if (y1 < ymin) | |
627 y1 = ymin; | |
628 | |
629 y2 = my + range; | |
630 if (y2 > ymax) | |
631 y2 = ymax; | |
632 | |
633 } while (range >= 1); | |
634 | |
635 #ifdef DEBUG | |
636 fprintf(stderr, "phods - MX: %d\tMY: %d\n", mx, my); | |
637 #endif | |
638 | |
639 /* half pixel search */ | |
640 *mx_ptr = mx; | |
641 *my_ptr = my; | |
642 return dminy; | |
643 } | |
644 | |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
645 |
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
646 #define Z_THRESHOLD 256 |
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
647 |
936 | 648 #define CHECK_SAD_HALF_MV(suffix, x, y) \ |
455 | 649 {\ |
1708 | 650 d= s->dsp.pix_abs[size][(x?1:0)+(y?2:0)](NULL, pix, ptr+((x)>>1), stride, h);\ |
936 | 651 d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\ |
455 | 652 COPY3_IF_LT(dminh, d, dx, x, dy, y)\ |
653 } | |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
654 |
936 | 655 static inline int sad_hpel_motion_search(MpegEncContext * s, |
0 | 656 int *mx_ptr, int *my_ptr, int dmin, |
1708 | 657 int pred_x, int pred_y, uint8_t *src_data[3], |
658 uint8_t *ref_data[6], int stride, int uvstride, | |
659 int size, int h, uint8_t * const mv_penalty) | |
0 | 660 { |
936 | 661 uint32_t *score_map= s->me.score_map; |
662 const int penalty_factor= s->me.sub_penalty_factor; | |
1708 | 663 int mx, my, dminh; |
1064 | 664 uint8_t *pix, *ptr; |
1708 | 665 const int xmin= s->me.xmin; |
666 const int ymin= s->me.ymin; | |
667 const int xmax= s->me.xmax; | |
668 const int ymax= s->me.ymax; | |
455 | 669 |
936 | 670 if(s->me.skip){ |
455 | 671 // printf("S"); |
672 *mx_ptr = 0; | |
673 *my_ptr = 0; | |
674 return dmin; | |
675 } | |
676 // printf("N"); | |
677 | |
1708 | 678 pix = src_data[0]; |
455 | 679 |
294 | 680 mx = *mx_ptr; |
681 my = *my_ptr; | |
1708 | 682 ptr = ref_data[0] + (my * stride) + mx; |
455 | 683 |
294 | 684 dminh = dmin; |
685 | |
686 if (mx > xmin && mx < xmax && | |
687 my > ymin && my < ymax) { | |
455 | 688 int dx=0, dy=0; |
689 int d, pen_x, pen_y; | |
690 const int index= (my<<ME_MAP_SHIFT) + mx; | |
691 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; | |
692 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]; | |
693 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]; | |
694 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; | |
695 mx<<=1; | |
696 my<<=1; | |
294 | 697 |
698 | |
699 pen_x= pred_x + mx; | |
700 pen_y= pred_y + my; | |
701 | |
1708 | 702 ptr-= stride; |
455 | 703 if(t<=b){ |
936 | 704 CHECK_SAD_HALF_MV(y2 , 0, -1) |
455 | 705 if(l<=r){ |
936 | 706 CHECK_SAD_HALF_MV(xy2, -1, -1) |
455 | 707 if(t+r<=b+l){ |
936 | 708 CHECK_SAD_HALF_MV(xy2, +1, -1) |
1708 | 709 ptr+= stride; |
455 | 710 }else{ |
1708 | 711 ptr+= stride; |
936 | 712 CHECK_SAD_HALF_MV(xy2, -1, +1) |
455 | 713 } |
936 | 714 CHECK_SAD_HALF_MV(x2 , -1, 0) |
455 | 715 }else{ |
936 | 716 CHECK_SAD_HALF_MV(xy2, +1, -1) |
455 | 717 if(t+l<=b+r){ |
936 | 718 CHECK_SAD_HALF_MV(xy2, -1, -1) |
1708 | 719 ptr+= stride; |
455 | 720 }else{ |
1708 | 721 ptr+= stride; |
936 | 722 CHECK_SAD_HALF_MV(xy2, +1, +1) |
455 | 723 } |
936 | 724 CHECK_SAD_HALF_MV(x2 , +1, 0) |
455 | 725 } |
726 }else{ | |
727 if(l<=r){ | |
728 if(t+l<=b+r){ | |
936 | 729 CHECK_SAD_HALF_MV(xy2, -1, -1) |
1708 | 730 ptr+= stride; |
455 | 731 }else{ |
1708 | 732 ptr+= stride; |
936 | 733 CHECK_SAD_HALF_MV(xy2, +1, +1) |
455 | 734 } |
936 | 735 CHECK_SAD_HALF_MV(x2 , -1, 0) |
736 CHECK_SAD_HALF_MV(xy2, -1, +1) | |
455 | 737 }else{ |
738 if(t+r<=b+l){ | |
936 | 739 CHECK_SAD_HALF_MV(xy2, +1, -1) |
1708 | 740 ptr+= stride; |
455 | 741 }else{ |
1708 | 742 ptr+= stride; |
936 | 743 CHECK_SAD_HALF_MV(xy2, -1, +1) |
455 | 744 } |
936 | 745 CHECK_SAD_HALF_MV(x2 , +1, 0) |
746 CHECK_SAD_HALF_MV(xy2, +1, +1) | |
455 | 747 } |
936 | 748 CHECK_SAD_HALF_MV(y2 , 0, +1) |
455 | 749 } |
750 mx+=dx; | |
751 my+=dy; | |
294 | 752 |
753 }else{ | |
455 | 754 mx<<=1; |
755 my<<=1; | |
294 | 756 } |
757 | |
758 *mx_ptr = mx; | |
759 *my_ptr = my; | |
455 | 760 return dminh; |
294 | 761 } |
762 | |
455 | 763 static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4) |
294 | 764 { |
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
|
765 const int xy= s->mb_x + s->mb_y*s->mb_stride; |
294 | 766 |
324 | 767 s->p_mv_table[xy][0] = mx; |
768 s->p_mv_table[xy][1] = my; | |
294 | 769 |
770 /* has allready been set to the 4 MV if 4MV is done */ | |
455 | 771 if(mv4){ |
294 | 772 int mot_xy= s->block_index[0]; |
773 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
774 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
|
775 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
|
776 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
|
777 s->current_picture.motion_val[0][mot_xy+1][1]= my; |
294 | 778 |
779 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
|
780 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
|
781 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
|
782 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
|
783 s->current_picture.motion_val[0][mot_xy+1][1]= my; |
294 | 784 } |
785 } | |
786 | |
1086 | 787 /** |
788 * get fullpel ME search limits. | |
789 */ | |
1708 | 790 static inline void get_limits(MpegEncContext *s, int x, int y) |
324 | 791 { |
1708 | 792 /* |
793 if(s->avctx->me_range) s->me.range= s->avctx->me_range >> 1; | |
794 else s->me.range= 16; | |
795 */ | |
324 | 796 if (s->unrestricted_mv) { |
1708 | 797 s->me.xmin = - x - 16; |
798 s->me.ymin = - y - 16; | |
799 s->me.xmax = - x + s->mb_width *16; | |
800 s->me.ymax = - y + s->mb_height*16; | |
324 | 801 } else { |
1708 | 802 s->me.xmin = - x; |
803 s->me.ymin = - y; | |
804 s->me.xmax = - x + s->mb_width *16 - 16; | |
805 s->me.ymax = - y + s->mb_height*16 - 16; | |
324 | 806 } |
807 } | |
808 | |
1708 | 809 static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) |
455 | 810 { |
1708 | 811 const int size= 1; |
812 const int h=8; | |
455 | 813 int block; |
814 int P[10][2]; | |
1013 | 815 int dmin_sum=0, mx4_sum=0, my4_sum=0; |
1162 | 816 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
|
817 int same=1; |
1708 | 818 const int stride= s->linesize; |
819 const int uvstride= s->uvlinesize; | |
820 const int xmin= s->me.xmin; | |
821 const int ymin= s->me.ymin; | |
822 const int xmax= s->me.xmax; | |
823 const int ymax= s->me.ymax; | |
455 | 824 |
825 for(block=0; block<4; block++){ | |
826 int mx4, my4; | |
827 int pred_x4, pred_y4; | |
828 int dmin4; | |
829 static const int off[4]= {2, 1, 1, -1}; | |
830 const int mot_stride = s->block_wrap[0]; | |
831 const int mot_xy = s->block_index[block]; | |
1708 | 832 const int block_x= (block&1); |
833 const int block_y= (block>>1); | |
834 uint8_t *src_data[3]= { | |
835 s->new_picture.data[0] + 8*(2*s->mb_x + block_x) + stride *8*(2*s->mb_y + block_y), //FIXME chroma? | |
836 s->new_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y), | |
837 s->new_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y) | |
838 }; | |
839 uint8_t *ref_data[3]= { | |
840 s->last_picture.data[0] + 8*(2*s->mb_x + block_x) + stride *8*(2*s->mb_y + block_y), //FIXME chroma? | |
841 s->last_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y), | |
842 s->last_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y) | |
843 }; | |
844 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
845 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
|
846 P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; |
455 | 847 |
1708 | 848 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
455 | 849 |
850 /* special case for first line */ | |
952 | 851 if (s->mb_y == 0 && block<2) { |
455 | 852 pred_x4= P_LEFT[0]; |
853 pred_y4= P_LEFT[1]; | |
854 } else { | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
855 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
|
856 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
|
857 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
|
858 P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; |
1708 | 859 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift); |
860 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
861 if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift); | |
862 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
455 | 863 |
864 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
865 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
866 | |
1013 | 867 // if(s->out_format == FMT_H263){ |
455 | 868 pred_x4 = P_MEDIAN[0]; |
869 pred_y4 = P_MEDIAN[1]; | |
1013 | 870 #if 0 |
455 | 871 }else { /* mpeg1 at least */ |
872 pred_x4= P_LEFT[0]; | |
873 pred_y4= P_LEFT[1]; | |
874 } | |
1013 | 875 #endif |
455 | 876 } |
877 P_MV1[0]= mx; | |
878 P_MV1[1]= my; | |
879 | |
1708 | 880 dmin4 = s->me.motion_search[1](s, &mx4, &my4, P, pred_x4, pred_y4, |
881 src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty); | |
455 | 882 |
1708 | 883 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, |
884 pred_x4, pred_y4, src_data, ref_data, stride, uvstride, size, h, mv_penalty); | |
1038 | 885 |
886 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ | |
1013 | 887 int dxy; |
1708 | 888 const int offset= ((block&1) + (block>>1)*stride)*8; |
1013 | 889 uint8_t *dest_y = s->me.scratchpad + offset; |
890 | |
891 if(s->quarter_sample){ | |
1708 | 892 uint8_t *ref= ref_data[0] + (mx4>>2) + (my4>>2)*stride + offset; |
1013 | 893 dxy = ((my4 & 3) << 2) | (mx4 & 3); |
894 | |
895 if(s->no_rounding) | |
1038 | 896 s->dsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y , ref , s->linesize); |
1013 | 897 else |
1708 | 898 s->dsp.put_qpel_pixels_tab [1][dxy](dest_y , ref , stride); |
1013 | 899 }else{ |
1708 | 900 uint8_t *ref= ref_data[0] + (mx4>>1) + (my4>>1)*stride + offset; |
1013 | 901 dxy = ((my4 & 1) << 1) | (mx4 & 1); |
902 | |
903 if(s->no_rounding) | |
1708 | 904 s->dsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h); |
1013 | 905 else |
1708 | 906 s->dsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h); |
1013 | 907 } |
908 dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*s->me.mb_penalty_factor; | |
909 }else | |
910 dmin_sum+= dmin4; | |
911 | |
912 if(s->quarter_sample){ | |
913 mx4_sum+= mx4/2; | |
914 my4_sum+= my4/2; | |
915 }else{ | |
916 mx4_sum+= mx4; | |
917 my4_sum+= my4; | |
918 } | |
919 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
920 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
|
921 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
|
922 |
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
923 if(mx4 != mx || my4 != my) same=0; |
1013 | 924 } |
925 | |
1494
3ee63c12ea30
optionally try to encode each MB with MV=<0,0> and choose the one with better RD
michaelni
parents:
1426
diff
changeset
|
926 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
|
927 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
|
928 |
1038 | 929 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ |
1708 | 930 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 | 931 } |
1013 | 932 |
933 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
934 int dxy; | |
935 int mx, my; | |
936 int offset; | |
937 | |
938 mx= ff_h263_round_chroma(mx4_sum); | |
939 my= ff_h263_round_chroma(my4_sum); | |
940 dxy = ((my & 1) << 1) | (mx & 1); | |
941 | |
942 offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize; | |
943 | |
944 if(s->no_rounding){ | |
945 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); | |
946 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); | |
947 }else{ | |
948 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); | |
949 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); | |
950 } | |
951 | |
1708 | 952 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); |
953 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 | 954 } |
955 | |
956 switch(s->avctx->mb_cmp&0xFF){ | |
957 /*case FF_CMP_SSE: | |
958 return dmin_sum+ 32*s->qscale*s->qscale;*/ | |
959 case FF_CMP_RD: | |
960 return dmin_sum; | |
961 default: | |
962 return dmin_sum+ 11*s->me.mb_penalty_factor; | |
963 } | |
455 | 964 } |
965 | |
1708 | 966 static int interlaced_search(MpegEncContext *s, uint8_t *frame_src_data[3], uint8_t *frame_ref_data[3], |
967 int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int f_code, int mx, int my) | |
968 { | |
969 const int size=0; | |
970 const int h=8; | |
971 int block; | |
972 int P[10][2]; | |
973 uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; | |
974 int same=1; | |
975 const int stride= 2*s->linesize; | |
976 const int uvstride= 2*s->uvlinesize; | |
977 int dmin_sum= 0; | |
978 const int mot_stride= s->mb_stride; | |
979 const int xy= s->mb_x + s->mb_y*mot_stride; | |
980 | |
981 s->me.ymin>>=1; | |
982 s->me.ymax>>=1; | |
983 | |
984 for(block=0; block<2; block++){ | |
985 int field_select; | |
986 int best_dmin= INT_MAX; | |
987 int best_field= -1; | |
988 | |
989 uint8_t *src_data[3]= { | |
990 frame_src_data[0] + s-> linesize*block, | |
991 frame_src_data[1] + s->uvlinesize*block, | |
992 frame_src_data[2] + s->uvlinesize*block | |
993 }; | |
994 | |
995 for(field_select=0; field_select<2; field_select++){ | |
996 int dmin, mx_i, my_i, pred_x, pred_y; | |
997 uint8_t *ref_data[3]= { | |
998 frame_ref_data[0] + s-> linesize*field_select, | |
999 frame_ref_data[1] + s->uvlinesize*field_select, | |
1000 frame_ref_data[2] + s->uvlinesize*field_select | |
1001 }; | |
1002 int16_t (*mv_table)[2]= mv_tables[block][field_select]; | |
1003 | |
1004 P_LEFT[0] = mv_table[xy - 1][0]; | |
1005 P_LEFT[1] = mv_table[xy - 1][1]; | |
1006 if(P_LEFT[0] > (s->me.xmax<<1)) P_LEFT[0] = (s->me.xmax<<1); | |
1007 | |
1008 pred_x= P_LEFT[0]; | |
1009 pred_y= P_LEFT[1]; | |
1010 | |
1011 if(s->mb_y){ | |
1012 P_TOP[0] = mv_table[xy - mot_stride][0]; | |
1013 P_TOP[1] = mv_table[xy - mot_stride][1]; | |
1014 P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; | |
1015 P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; | |
1016 if(P_TOP[1] > (s->me.ymax<<1)) P_TOP[1] = (s->me.ymax<<1); | |
1017 if(P_TOPRIGHT[0] < (s->me.xmin<<1)) P_TOPRIGHT[0]= (s->me.xmin<<1); | |
1018 if(P_TOPRIGHT[0] > (s->me.xmax<<1)) P_TOPRIGHT[0]= (s->me.xmax<<1); | |
1019 if(P_TOPRIGHT[1] > (s->me.ymax<<1)) P_TOPRIGHT[1]= (s->me.ymax<<1); | |
1020 | |
1021 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
1022 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1023 } | |
1024 P_MV1[0]= mx; //FIXME not correct if block != field_select | |
1025 P_MV1[1]= my / 2; | |
1026 | |
1027 dmin = s->me.motion_search[4](s, &mx_i, &my_i, P, pred_x, pred_y, | |
1028 src_data, ref_data, stride, uvstride, mv_table, (1<<16)>>1, mv_penalty); | |
1029 | |
1030 dmin= s->me.sub_motion_search(s, &mx_i, &my_i, dmin, | |
1031 pred_x, pred_y, src_data, ref_data, stride, uvstride, size, h, mv_penalty); | |
1032 | |
1033 mv_table[xy][0]= mx_i; | |
1034 mv_table[xy][1]= my_i; | |
1035 | |
1036 if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ | |
1037 int dxy; | |
1038 | |
1039 //FIXME chroma ME | |
1040 uint8_t *ref= ref_data[0] + (mx_i>>1) + (my_i>>1)*stride; | |
1041 dxy = ((my_i & 1) << 1) | (mx_i & 1); | |
1042 | |
1043 if(s->no_rounding){ | |
1044 s->dsp.put_no_rnd_pixels_tab[size][dxy](s->me.scratchpad, ref , stride, h); | |
1045 }else{ | |
1046 s->dsp.put_pixels_tab [size][dxy](s->me.scratchpad, ref , stride, h); | |
1047 } | |
1048 dmin= s->dsp.mb_cmp[size](s, src_data[0], s->me.scratchpad, stride, h); | |
1049 dmin+= (mv_penalty[mx_i-pred_x] + mv_penalty[my_i-pred_y] + 1)*s->me.mb_penalty_factor; | |
1050 }else | |
1051 dmin+= s->me.mb_penalty_factor; //field_select bits | |
1052 | |
1053 dmin += field_select != block; //slightly prefer same field | |
1054 | |
1055 if(dmin < best_dmin){ | |
1056 best_dmin= dmin; | |
1057 best_field= field_select; | |
1058 } | |
1059 } | |
1060 { | |
1061 int16_t (*mv_table)[2]= mv_tables[block][best_field]; | |
1062 | |
1063 if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all | |
1064 if(mv_table[xy][1]&1) same=0; | |
1065 if(mv_table[xy][1]*2 != my) same=0; | |
1066 if(best_field != block) same=0; | |
1067 } | |
1068 | |
1069 field_select_tables[block][xy]= best_field; | |
1070 dmin_sum += best_dmin; | |
1071 } | |
1072 | |
1073 s->me.ymin<<=1; | |
1074 s->me.ymax<<=1; | |
1075 | |
1076 if(same) | |
1077 return INT_MAX; | |
1078 | |
1079 switch(s->avctx->mb_cmp&0xFF){ | |
1080 /*case FF_CMP_SSE: | |
1081 return dmin_sum+ 32*s->qscale*s->qscale;*/ | |
1082 case FF_CMP_RD: | |
1083 return dmin_sum; | |
1084 default: | |
1085 return dmin_sum+ 11*s->me.mb_penalty_factor; | |
1086 } | |
1087 } | |
1088 | |
324 | 1089 void ff_estimate_p_frame_motion(MpegEncContext * s, |
1090 int mb_x, int mb_y) | |
0 | 1091 { |
1064 | 1092 uint8_t *pix, *ppix; |
1708 | 1093 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
|
1094 int pred_x=0, pred_y=0; |
455 | 1095 int P[10][2]; |
280 | 1096 const int shift= 1+s->quarter_sample; |
294 | 1097 int mb_type=0; |
903 | 1098 uint8_t *ref_picture= s->last_picture.data[0]; |
1099 Picture * const pic= &s->current_picture; | |
1162 | 1100 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
1708 | 1101 const int stride= s->linesize; |
1102 const int uvstride= s->uvlinesize; | |
1103 uint8_t *src_data[3]= { | |
1104 s->new_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1105 s->new_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1106 s->new_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1107 }; | |
1108 uint8_t *ref_data[3]= { | |
1109 s->last_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1110 s->last_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1111 s->last_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1112 }; | |
1113 | |
936 | 1114 assert(s->quarter_sample==0 || s->quarter_sample==1); |
1115 | |
1116 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | |
1117 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | |
1013 | 1118 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
0 | 1119 |
1708 | 1120 get_limits(s, 16*mb_x, 16*mb_y); |
936 | 1121 s->me.skip=0; |
324 | 1122 |
320
cda7d0857baf
- ME setting moved to AVCodecContext/MpegEncContext, no longer a global.
pulento
parents:
304
diff
changeset
|
1123 switch(s->me_method) { |
0 | 1124 case ME_ZERO: |
1125 default: | |
1126 no_motion_search(s, &mx, &my); | |
455 | 1127 mx-= mb_x*16; |
1128 my-= mb_y*16; | |
0 | 1129 dmin = 0; |
1130 break; | |
1708 | 1131 #if 0 |
0 | 1132 case ME_FULL: |
1708 | 1133 dmin = full_motion_search(s, &mx, &my, range, ref_picture); |
455 | 1134 mx-= mb_x*16; |
1135 my-= mb_y*16; | |
0 | 1136 break; |
1137 case ME_LOG: | |
1708 | 1138 dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1139 mx-= mb_x*16; |
1140 my-= mb_y*16; | |
0 | 1141 break; |
1142 case ME_PHODS: | |
1708 | 1143 dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1144 mx-= mb_x*16; |
1145 my-= mb_y*16; | |
0 | 1146 break; |
1708 | 1147 #endif |
288 | 1148 case ME_X1: |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
1149 case ME_EPZS: |
288 | 1150 { |
294 | 1151 const int mot_stride = s->block_wrap[0]; |
1152 const int mot_xy = s->block_index[0]; | |
288 | 1153 |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1154 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
|
1155 P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; |
288 | 1156 |
1708 | 1157 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
280 | 1158 |
952 | 1159 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
|
1160 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
|
1161 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
|
1162 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
|
1163 P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1]; |
1708 | 1164 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift); |
1165 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
1166 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
280 | 1167 |
455 | 1168 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); |
1169 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1170 | |
1171 if(s->out_format == FMT_H263){ | |
1172 pred_x = P_MEDIAN[0]; | |
1173 pred_y = P_MEDIAN[1]; | |
1174 }else { /* mpeg1 at least */ | |
1175 pred_x= P_LEFT[0]; | |
1176 pred_y= P_LEFT[1]; | |
1177 } | |
952 | 1178 }else{ |
1179 pred_x= P_LEFT[0]; | |
1180 pred_y= P_LEFT[1]; | |
288 | 1181 } |
952 | 1182 |
280 | 1183 } |
1708 | 1184 dmin = s->me.motion_search[0](s, &mx, &my, P, pred_x, pred_y, |
1185 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
|
1186 |
277
5cb2978e701f
new motion estimation (epzs) not complete yet but allready pretty good :)
michaelni
parents:
275
diff
changeset
|
1187 break; |
0 | 1188 } |
1189 | |
1190 /* intra / predictive decision */ | |
1191 xx = mb_x * 16; | |
1192 yy = mb_y * 16; | |
1193 | |
1708 | 1194 pix = src_data[0]; |
455 | 1195 /* At this point (mx,my) are full-pell and the relative displacement */ |
1708 | 1196 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
|
1197 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1198 sum = s->dsp.pix_sum(pix, s->linesize); |
455 | 1199 |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1200 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; |
1708 | 1201 vard = (s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16)+128)>>8; |
608 | 1202 |
455 | 1203 //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
|
1204 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
|
1205 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
|
1206 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
|
1207 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; |
903 | 1208 pic->mb_var_sum += varc; |
1209 pic->mc_mb_var_sum += vard; | |
455 | 1210 //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
|
1211 |
0 | 1212 #if 0 |
233
3f5b72726118
- More work on preliminary bit rate control, just to be able to get an
pulento
parents:
232
diff
changeset
|
1213 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
|
1214 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); |
0 | 1215 #endif |
1389 | 1216 if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
608 | 1217 if (vard <= 64 || vard < varc) |
1218 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); | |
1219 else | |
913 | 1220 s->scene_change_score+= s->qscale; |
608 | 1221 |
294 | 1222 if (vard*2 + 200 > varc) |
1708 | 1223 mb_type|= CANDIDATE_MB_TYPE_INTRA; |
294 | 1224 if (varc*2 + 200 > vard){ |
1708 | 1225 mb_type|= CANDIDATE_MB_TYPE_INTER; |
1226 s->me.sub_motion_search(s, &mx, &my, dmin, | |
1227 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
|
1228 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
|
1229 if(mx || my) |
1708 | 1230 mb_type |= CANDIDATE_MB_TYPE_SKIPED; //FIXME check difference |
304 | 1231 }else{ |
936 | 1232 mx <<=shift; |
1233 my <<=shift; | |
0 | 1234 } |
455 | 1235 if((s->flags&CODEC_FLAG_4MV) |
936 | 1236 && !s->me.skip && varc>50 && vard>10){ |
1708 | 1237 if(h263_mv4_search(s, mx, my, shift) < INT_MAX) |
1238 mb_type|=CANDIDATE_MB_TYPE_INTER4V; | |
455 | 1239 |
1240 set_p_mv_tables(s, mx, my, 0); | |
1241 }else | |
1242 set_p_mv_tables(s, mx, my, 1); | |
1708 | 1243 if((s->flags&CODEC_FLAG_INTERLACED_ME) |
1244 && !s->me.skip){ //FIXME varc/d checks | |
1245 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) | |
1246 mb_type |= CANDIDATE_MB_TYPE_INTER_I; | |
1247 } | |
294 | 1248 }else{ |
1633 | 1249 int intra_score, i; |
1708 | 1250 mb_type= CANDIDATE_MB_TYPE_INTER; |
1013 | 1251 |
1708 | 1252 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, |
1253 pred_x, pred_y, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1254 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) |
1708 | 1255 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, src_data, ref_data, stride, uvstride, mv_penalty); |
1013 | 1256 |
1257 if((s->flags&CODEC_FLAG_4MV) | |
1258 && !s->me.skip && varc>50 && vard>10){ | |
1708 | 1259 int dmin4= h263_mv4_search(s, mx, my, shift); |
1013 | 1260 if(dmin4 < dmin){ |
1708 | 1261 mb_type= CANDIDATE_MB_TYPE_INTER4V; |
1013 | 1262 dmin=dmin4; |
1263 } | |
1264 } | |
1708 | 1265 if((s->flags&CODEC_FLAG_INTERLACED_ME) |
1266 && !s->me.skip){ //FIXME varc/d checks | |
1267 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); | |
1268 if(dmin_i < dmin){ | |
1269 mb_type = CANDIDATE_MB_TYPE_INTER_I; | |
1270 dmin= dmin_i; | |
1271 } | |
1272 } | |
1633 | 1273 |
1274 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; | |
1708 | 1275 set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V); |
1633 | 1276 |
1277 /* get intra luma score */ | |
1278 if((s->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ | |
1279 intra_score= (varc<<8) - 500; //FIXME dont scale it down so we dont have to fix it | |
1280 }else{ | |
1281 int mean= (sum+128)>>8; | |
1282 mean*= 0x01010101; | |
1283 | |
1284 for(i=0; i<16; i++){ | |
1285 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 0]) = mean; | |
1286 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 4]) = mean; | |
1287 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 8]) = mean; | |
1288 *(uint32_t*)(&s->me.scratchpad[i*s->linesize+12]) = mean; | |
1289 } | |
1290 | |
1708 | 1291 intra_score= s->dsp.mb_cmp[0](s, s->me.scratchpad, pix, s->linesize, 16); |
1633 | 1292 } |
1293 #if 0 //FIXME | |
1294 /* get chroma score */ | |
1295 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
1296 for(i=1; i<3; i++){ | |
1297 uint8_t *dest_c; | |
1298 int mean; | |
1299 | |
1300 if(s->out_format == FMT_H263){ | |
1301 mean= (s->dc_val[i][mb_x + (mb_y+1)*(s->mb_width+2)] + 4)>>3; //FIXME not exact but simple ;) | |
1302 }else{ | |
1303 mean= (s->last_dc[i] + 4)>>3; | |
1304 } | |
1305 dest_c = s->new_picture.data[i] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |
1306 | |
1307 mean*= 0x01010101; | |
1308 for(i=0; i<8; i++){ | |
1309 *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 0]) = mean; | |
1310 *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 4]) = mean; | |
1311 } | |
1312 | |
1313 intra_score+= s->dsp.mb_cmp[1](s, s->me.scratchpad, dest_c, s->uvlinesize); | |
1314 } | |
1315 } | |
1316 #endif | |
1317 intra_score += s->me.mb_penalty_factor*16; | |
1013 | 1318 |
1633 | 1319 if(intra_score < dmin){ |
1708 | 1320 mb_type= CANDIDATE_MB_TYPE_INTRA; |
1321 s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup | |
1633 | 1322 }else |
1323 s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= 0; | |
1324 | |
1325 if (vard <= 64 || vard < varc) { //FIXME | |
608 | 1326 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
294 | 1327 }else{ |
1011 | 1328 s->scene_change_score+= s->qscale; |
294 | 1329 } |
1330 } | |
284 | 1331 |
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
|
1332 s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type; |
0 | 1333 } |
1334 | |
951 | 1335 int ff_pre_estimate_p_frame_motion(MpegEncContext * s, |
1336 int mb_x, int mb_y) | |
1337 { | |
1708 | 1338 int mx, my, dmin; |
951 | 1339 int pred_x=0, pred_y=0; |
1340 int P[10][2]; | |
1341 const int shift= 1+s->quarter_sample; | |
1162 | 1342 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
|
1343 const int xy= mb_x + mb_y*s->mb_stride; |
1708 | 1344 const int stride= s->linesize; |
1345 const int uvstride= s->uvlinesize; | |
1346 uint8_t *src_data[3]= { | |
1347 s->new_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1348 s->new_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1349 s->new_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1350 }; | |
1351 uint8_t *ref_data[3]= { | |
1352 s->last_picture.data[0] + 16*(mb_x + stride*mb_y), | |
1353 s->last_picture.data[1] + 8*(mb_x + uvstride*mb_y), | |
1354 s->last_picture.data[2] + 8*(mb_x + uvstride*mb_y) | |
1355 }; | |
951 | 1356 |
1357 assert(s->quarter_sample==0 || s->quarter_sample==1); | |
1358 | |
954 | 1359 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp); |
951 | 1360 |
1708 | 1361 get_limits(s, 16*mb_x, 16*mb_y); |
951 | 1362 s->me.skip=0; |
1363 | |
1364 P_LEFT[0] = s->p_mv_table[xy + 1][0]; | |
1365 P_LEFT[1] = s->p_mv_table[xy + 1][1]; | |
1366 | |
1708 | 1367 if(P_LEFT[0] < (s->me.xmin<<shift)) P_LEFT[0] = (s->me.xmin<<shift); |
951 | 1368 |
1369 /* special case for first line */ | |
1370 if (mb_y == s->mb_height-1) { | |
1371 pred_x= P_LEFT[0]; | |
1372 pred_y= P_LEFT[1]; | |
952 | 1373 P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]= |
1374 P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME | |
951 | 1375 } 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
|
1376 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
|
1377 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
|
1378 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
|
1379 P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1]; |
1708 | 1380 if(P_TOP[1] < (s->me.ymin<<shift)) P_TOP[1] = (s->me.ymin<<shift); |
1381 if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift); | |
1382 if(P_TOPRIGHT[1] < (s->me.ymin<<shift)) P_TOPRIGHT[1]= (s->me.ymin<<shift); | |
951 | 1383 |
1384 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
1385 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1386 | |
952 | 1387 pred_x = P_MEDIAN[0]; |
1388 pred_y = P_MEDIAN[1]; | |
951 | 1389 } |
1708 | 1390 dmin = s->me.pre_motion_search(s, &mx, &my, P, pred_x, pred_y, |
1391 src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty); | |
952 | 1392 |
951 | 1393 s->p_mv_table[xy][0] = mx<<shift; |
1394 s->p_mv_table[xy][1] = my<<shift; | |
1395 | |
1396 return dmin; | |
1397 } | |
1398 | |
1057 | 1399 static int ff_estimate_motion_b(MpegEncContext * s, |
1708 | 1400 int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *src_data[3], |
1401 uint8_t *ref_data[3], int stride, int uvstride, int f_code) | |
0 | 1402 { |
1708 | 1403 int mx, my, dmin; |
324 | 1404 int pred_x=0, pred_y=0; |
455 | 1405 int P[10][2]; |
324 | 1406 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
|
1407 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
|
1408 const int mot_xy = mb_y*mot_stride + mb_x; |
1708 | 1409 uint8_t * const ref_picture= ref_data[0] - 16*s->mb_x - 16*s->mb_y*s->linesize; //FIXME ugly |
1162 | 1410 uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; |
948 | 1411 int mv_scale; |
936 | 1412 |
1413 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | |
1414 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | |
1013 | 1415 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
936 | 1416 |
1708 | 1417 get_limits(s, 16*mb_x, 16*mb_y); |
324 | 1418 |
1419 switch(s->me_method) { | |
1420 case ME_ZERO: | |
1421 default: | |
1422 no_motion_search(s, &mx, &my); | |
1423 dmin = 0; | |
455 | 1424 mx-= mb_x*16; |
1425 my-= mb_y*16; | |
324 | 1426 break; |
1708 | 1427 #if 0 |
324 | 1428 case ME_FULL: |
1708 | 1429 dmin = full_motion_search(s, &mx, &my, range, ref_picture); |
455 | 1430 mx-= mb_x*16; |
1431 my-= mb_y*16; | |
324 | 1432 break; |
1433 case ME_LOG: | |
1708 | 1434 dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1435 mx-= mb_x*16; |
1436 my-= mb_y*16; | |
324 | 1437 break; |
1438 case ME_PHODS: | |
1708 | 1439 dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); |
455 | 1440 mx-= mb_x*16; |
1441 my-= mb_y*16; | |
324 | 1442 break; |
1708 | 1443 #endif |
324 | 1444 case ME_X1: |
1445 case ME_EPZS: | |
1446 { | |
455 | 1447 P_LEFT[0] = mv_table[mot_xy - 1][0]; |
1448 P_LEFT[1] = mv_table[mot_xy - 1][1]; | |
324 | 1449 |
1708 | 1450 if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift); |
324 | 1451 |
1452 /* special case for first line */ | |
952 | 1453 if (mb_y) { |
455 | 1454 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; |
1455 P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; | |
1456 P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1 ][0]; | |
1457 P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1 ][1]; | |
1708 | 1458 if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1]= (s->me.ymax<<shift); |
1459 if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift); | |
1460 if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift); | |
324 | 1461 |
455 | 1462 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); |
1463 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
324 | 1464 } |
455 | 1465 pred_x= P_LEFT[0]; |
1466 pred_y= P_LEFT[1]; | |
324 | 1467 } |
948 | 1468 |
1469 if(mv_table == s->b_forw_mv_table){ | |
1470 mv_scale= (s->pb_time<<16) / (s->pp_time<<shift); | |
1471 }else{ | |
1472 mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift); | |
1473 } | |
1474 | |
1708 | 1475 dmin = s->me.motion_search[0](s, &mx, &my, P, pred_x, pred_y, |
1476 src_data, ref_data, stride, uvstride, s->p_mv_table, mv_scale, mv_penalty); | |
324 | 1477 |
1478 break; | |
1479 } | |
1480 | |
1708 | 1481 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, |
1482 pred_x, pred_y, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1483 |
1484 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1485 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, src_data, ref_data, stride, uvstride, mv_penalty); |
1013 | 1486 |
455 | 1487 //printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my); |
324 | 1488 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; |
1489 mv_table[mot_xy][0]= mx; | |
1490 mv_table[mot_xy][1]= my; | |
936 | 1491 |
327 | 1492 return dmin; |
324 | 1493 } |
1494 | |
1708 | 1495 static inline int check_bidir_mv(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1496 int stride, int uvstride, | |
327 | 1497 int motion_fx, int motion_fy, |
1498 int motion_bx, int motion_by, | |
1499 int pred_fx, int pred_fy, | |
1708 | 1500 int pred_bx, int pred_by, |
1501 int size, int h) | |
327 | 1502 { |
1503 //FIXME optimize? | |
936 | 1504 //FIXME move into template? |
1505 //FIXME better f_code prediction (max mv & distance) | |
1708 | 1506 //FIXME pointers |
1162 | 1507 uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame |
936 | 1508 uint8_t *dest_y = s->me.scratchpad; |
327 | 1509 uint8_t *ptr; |
1510 int dxy; | |
1511 int src_x, src_y; | |
1512 int fbmin; | |
1513 | |
936 | 1514 if(s->quarter_sample){ |
1515 dxy = ((motion_fy & 3) << 2) | (motion_fx & 3); | |
1708 | 1516 src_x = motion_fx >> 2; |
1517 src_y = motion_fy >> 2; | |
327 | 1518 |
1708 | 1519 ptr = ref_data[0] + (src_y * stride) + src_x; |
1520 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
|
1521 |
936 | 1522 dxy = ((motion_by & 3) << 2) | (motion_bx & 3); |
1708 | 1523 src_x = motion_bx >> 2; |
1524 src_y = motion_by >> 2; | |
936 | 1525 |
1708 | 1526 ptr = ref_data[3] + (src_y * stride) + src_x; |
1527 s->dsp.avg_qpel_pixels_tab[size][dxy](dest_y , ptr , stride); | |
936 | 1528 }else{ |
1529 dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); | |
1708 | 1530 src_x = motion_fx >> 1; |
1531 src_y = motion_fy >> 1; | |
327 | 1532 |
1708 | 1533 ptr = ref_data[0] + (src_y * stride) + src_x; |
1534 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
|
1535 |
936 | 1536 dxy = ((motion_by & 1) << 1) | (motion_bx & 1); |
1708 | 1537 src_x = motion_bx >> 1; |
1538 src_y = motion_by >> 1; | |
936 | 1539 |
1708 | 1540 ptr = ref_data[3] + (src_y * stride) + src_x; |
1541 s->dsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h); | |
936 | 1542 } |
853
eacc2dd8fd9d
* using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents:
847
diff
changeset
|
1543 |
1013 | 1544 fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.mb_penalty_factor |
1545 +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.mb_penalty_factor | |
1708 | 1546 + s->dsp.mb_cmp[size](s, src_data[0], dest_y, stride, h); //FIXME new_pic |
1013 | 1547 |
1548 if(s->avctx->mb_cmp&FF_CMP_CHROMA){ | |
1549 } | |
1550 //FIXME CHROMA !!! | |
1551 | |
327 | 1552 return fbmin; |
1553 } | |
1554 | |
1555 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ | |
1708 | 1556 static inline int bidir_refine(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1557 int stride, int uvstride, | |
327 | 1558 int mb_x, int mb_y) |
1559 { | |
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
|
1560 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
|
1561 const int xy = mb_y *mot_stride + mb_x; |
327 | 1562 int fbmin; |
1563 int pred_fx= s->b_bidir_forw_mv_table[xy-1][0]; | |
1564 int pred_fy= s->b_bidir_forw_mv_table[xy-1][1]; | |
1565 int pred_bx= s->b_bidir_back_mv_table[xy-1][0]; | |
1566 int pred_by= s->b_bidir_back_mv_table[xy-1][1]; | |
1567 int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; | |
1568 int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; | |
1569 int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; | |
1570 int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; | |
1571 | |
1572 //FIXME do refinement and add flag | |
1573 | |
1708 | 1574 fbmin= check_bidir_mv(s, src_data, ref_data, stride, uvstride, |
327 | 1575 motion_fx, motion_fy, |
1576 motion_bx, motion_by, | |
1577 pred_fx, pred_fy, | |
1708 | 1578 pred_bx, pred_by, |
1579 0, 16); | |
327 | 1580 |
1581 return fbmin; | |
1582 } | |
1583 | |
1708 | 1584 static inline int direct_search(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6], |
1585 int stride, int uvstride, | |
327 | 1586 int mb_x, int mb_y) |
324 | 1587 { |
455 | 1588 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
|
1589 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
|
1590 const int mot_xy = mb_y*mot_stride + mb_x; |
936 | 1591 const int shift= 1+s->quarter_sample; |
1592 int dmin, i; | |
327 | 1593 const int time_pp= s->pp_time; |
664 | 1594 const int time_pb= s->pb_time; |
936 | 1595 int mx, my, xmin, xmax, ymin, ymax; |
327 | 1596 int16_t (*mv_table)[2]= s->b_direct_mv_table; |
1162 | 1597 uint8_t * const mv_penalty= s->me.mv_penalty[1] + MAX_MV; |
936 | 1598 |
1599 ymin= xmin=(-32)>>shift; | |
1600 ymax= xmax= 31>>shift; | |
1601 | |
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
|
1602 if(IS_8X8(s->next_picture.mb_type[mot_xy])){ |
936 | 1603 s->mv_type= MV_TYPE_8X8; |
1604 }else{ | |
1605 s->mv_type= MV_TYPE_16X16; | |
327 | 1606 } |
936 | 1607 |
1608 for(i=0; i<4; i++){ | |
1609 int index= s->block_index[i]; | |
1610 int min, max; | |
1611 | |
1668
30746f429df6
move motion_val & mb_type to AVFrame patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michael
parents:
1634
diff
changeset
|
1612 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
|
1613 s->me.co_located_mv[i][1]= s->next_picture.motion_val[0][index][1]; |
936 | 1614 s->me.direct_basis_mv[i][0]= s->me.co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); |
1615 s->me.direct_basis_mv[i][1]= s->me.co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); | |
1616 // 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); | |
1617 // 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); | |
1618 | |
1619 max= FFMAX(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift; | |
1620 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 | 1621 max+= (2*mb_x + (i& 1))*8 + 1; // +-1 is for the simpler rounding |
1622 min+= (2*mb_x + (i& 1))*8 - 1; | |
960 | 1623 xmax= FFMIN(xmax, s->width - max); |
1624 xmin= FFMAX(xmin, - 16 - min); | |
936 | 1625 |
1626 max= FFMAX(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift; | |
1627 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 | 1628 max+= (2*mb_y + (i>>1))*8 + 1; // +-1 is for the simpler rounding |
1629 min+= (2*mb_y + (i>>1))*8 - 1; | |
960 | 1630 ymax= FFMIN(ymax, s->height - max); |
1631 ymin= FFMAX(ymin, - 16 - min); | |
936 | 1632 |
1633 if(s->mv_type == MV_TYPE_16X16) break; | |
327 | 1634 } |
936 | 1635 |
1636 assert(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16); | |
1637 | |
1638 if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){ | |
1639 s->b_direct_mv_table[mot_xy][0]= 0; | |
1640 s->b_direct_mv_table[mot_xy][1]= 0; | |
1641 | |
1642 return 256*256*256*64; | |
1643 } | |
1708 | 1644 |
1645 s->me.xmin= xmin; | |
1646 s->me.ymin= ymin; | |
1647 s->me.xmax= xmax; | |
1648 s->me.ymax= ymax; | |
936 | 1649 |
950 | 1650 P_LEFT[0] = clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift); |
1651 P_LEFT[1] = clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift); | |
1652 | |
1653 /* special case for first line */ | |
952 | 1654 if (mb_y) { |
950 | 1655 P_TOP[0] = clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift); |
1656 P_TOP[1] = clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift); | |
1657 P_TOPRIGHT[0] = clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift); | |
1658 P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift); | |
1659 | |
1660 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); | |
1661 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | |
1662 } | |
1013 | 1663 |
1664 //FIXME direct_search ptr in context!!! (needed for chroma anyway or this will get messy) | |
936 | 1665 if(s->flags&CODEC_FLAG_QPEL){ |
1708 | 1666 dmin = simple_direct_qpel_epzs_motion_search(s, &mx, &my, P, 0, 0, |
1667 src_data, ref_data, stride, uvstride, mv_table, 1<<14, mv_penalty); | |
1668 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, | |
1669 0, 0, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1670 |
1671 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1672 dmin= simple_direct_qpel_qpel_get_mb_score(s, mx, my, 0, 0, src_data, ref_data, stride, uvstride, mv_penalty); |
936 | 1673 }else{ |
1708 | 1674 dmin = simple_direct_hpel_epzs_motion_search(s, &mx, &my, P, 0, 0, |
1675 src_data, ref_data, stride, uvstride, mv_table, 1<<15, mv_penalty); | |
1676 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, | |
1677 0, 0, src_data, ref_data, stride, uvstride, 0, 16, mv_penalty); | |
1013 | 1678 |
1679 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip) | |
1708 | 1680 dmin= simple_direct_hpel_hpel_get_mb_score(s, mx, my, 0, 0, src_data, ref_data, stride, uvstride, mv_penalty); |
327 | 1681 } |
1708 | 1682 |
1683 get_limits(s, 16*mb_x, 16*mb_y); //restore s->me.?min/max, maybe not needed | |
327 | 1684 |
1685 s->b_direct_mv_table[mot_xy][0]= mx; | |
1686 s->b_direct_mv_table[mot_xy][1]= my; | |
1687 return dmin; | |
324 | 1688 } |
1689 | |
1690 void ff_estimate_b_frame_motion(MpegEncContext * s, | |
1691 int mb_x, int mb_y) | |
1692 { | |
1013 | 1693 const int penalty_factor= s->me.mb_penalty_factor; |
1708 | 1694 int fmin, bmin, dmin, fbmin, bimin, fimin; |
327 | 1695 int type=0; |
1708 | 1696 const int stride= s->linesize; |
1697 const int uvstride= s->uvlinesize; | |
1698 uint8_t *src_data[3]= { | |
1699 s->new_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1700 s->new_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1701 s->new_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y) | |
1702 }; | |
1703 uint8_t *ref_data[6]= { | |
1704 s->last_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1705 s->last_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1706 s->last_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y), | |
1707 s->next_picture.data[0] + 16*(s->mb_x + stride*s->mb_y), | |
1708 s->next_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y), | |
1709 s->next_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y) | |
1710 }; | |
327 | 1711 |
1426 | 1712 s->me.skip=0; |
1713 if (s->codec_id == CODEC_ID_MPEG4) | |
1708 | 1714 dmin= direct_search(s, src_data, ref_data, stride, uvstride, mb_x, mb_y); |
1426 | 1715 else |
1716 dmin= INT_MAX; | |
1708 | 1717 //FIXME penalty stuff for non mpeg4 |
1426 | 1718 s->me.skip=0; |
1708 | 1719 fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, src_data, |
1720 ref_data, stride, uvstride, s->f_code) + 3*penalty_factor; | |
1426 | 1721 |
1722 s->me.skip=0; | |
1708 | 1723 bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, src_data, |
1724 ref_data+3, stride, uvstride, s->b_code) + 2*penalty_factor; | |
324 | 1725 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); |
327 | 1726 |
1426 | 1727 s->me.skip=0; |
1708 | 1728 fbmin= bidir_refine(s, src_data, ref_data, stride, uvstride, mb_x, mb_y) + penalty_factor; |
1013 | 1729 //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); |
1708 | 1730 |
1731 if(s->flags & CODEC_FLAG_INTERLACED_ME){ | |
1732 const int xy = mb_y*s->mb_stride + mb_x; | |
1733 | |
1734 //FIXME mb type penalty | |
1735 s->me.skip=0; | |
1736 fimin= interlaced_search(s, src_data, ref_data , | |
1737 s->b_field_mv_table[0], s->b_field_select_table[0], s->f_code, | |
1738 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); | |
1739 bimin= interlaced_search(s, src_data, ref_data+3, | |
1740 s->b_field_mv_table[1], s->b_field_select_table[1], s->b_code, | |
1741 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1]); | |
1742 }else | |
1743 fimin= bimin= INT_MAX; | |
1744 | |
612 | 1745 { |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1746 int score= fmin; |
1708 | 1747 type = CANDIDATE_MB_TYPE_FORWARD; |
327 | 1748 |
1426 | 1749 if (dmin <= score){ |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1750 score = dmin; |
1708 | 1751 type = CANDIDATE_MB_TYPE_DIRECT; |
327 | 1752 } |
1753 if(bmin<score){ | |
1754 score=bmin; | |
1708 | 1755 type= CANDIDATE_MB_TYPE_BACKWARD; |
327 | 1756 } |
1757 if(fbmin<score){ | |
1758 score=fbmin; | |
1708 | 1759 type= CANDIDATE_MB_TYPE_BIDIR; |
1760 } | |
1761 if(fimin<score){ | |
1762 score=fimin; | |
1763 type= CANDIDATE_MB_TYPE_FORWARD_I; | |
1764 } | |
1765 if(bimin<score){ | |
1766 score=bimin; | |
1767 type= CANDIDATE_MB_TYPE_BACKWARD_I; | |
327 | 1768 } |
1013 | 1769 |
807
0e1d375c537f
fixing q>0.0 assert failure caused by overflow of variance for b frames
michaelni
parents:
765
diff
changeset
|
1770 score= ((unsigned)(score*score + 128*256))>>16; |
903 | 1771 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
|
1772 s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE |
327 | 1773 } |
612 | 1774 |
1389 | 1775 if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
1708 | 1776 type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT; |
1777 if(fimin < INT_MAX) | |
1778 type |= CANDIDATE_MB_TYPE_FORWARD_I; | |
1779 if(bimin < INT_MAX) | |
1780 type |= CANDIDATE_MB_TYPE_BACKWARD_I; | |
1781 if(fimin < INT_MAX && bimin < INT_MAX){ | |
1782 type |= CANDIDATE_MB_TYPE_BIDIR_I; | |
1783 } | |
1784 //FIXME something smarter | |
1785 if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB | |
612 | 1786 } |
1787 | |
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
|
1788 s->mb_type[mb_y*s->mb_stride + mb_x]= type; |
324 | 1789 } |
0 | 1790 |
324 | 1791 /* find best f_code for ME which do unlimited searches */ |
1792 int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) | |
1793 { | |
1794 if(s->me_method>=ME_EPZS){ | |
455 | 1795 int score[8]; |
324 | 1796 int i, y; |
1064 | 1797 uint8_t * fcode_tab= s->fcode_tab; |
455 | 1798 int best_fcode=-1; |
1799 int best_score=-10000000; | |
324 | 1800 |
936 | 1801 for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); |
324 | 1802 |
1803 for(y=0; y<s->mb_height; y++){ | |
1804 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
|
1805 int xy= y*s->mb_stride; |
324 | 1806 for(x=0; x<s->mb_width; x++){ |
1634 | 1807 if(s->mb_type[xy] & type){ |
847 | 1808 int fcode= FFMAX(fcode_tab[mv_table[xy][0] + MAX_MV], |
1809 fcode_tab[mv_table[xy][1] + MAX_MV]); | |
455 | 1810 int j; |
1811 | |
1812 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
|
1813 if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) |
455 | 1814 score[j]-= 170; |
1815 } | |
324 | 1816 } |
1817 xy++; | |
1818 } | |
1819 } | |
455 | 1820 |
1821 for(i=1; i<8; i++){ | |
1822 if(score[i] > best_score){ | |
1823 best_score= score[i]; | |
1824 best_fcode= i; | |
1825 } | |
1826 // printf("%d %d\n", i, score[i]); | |
1827 } | |
327 | 1828 |
324 | 1829 // printf("fcode: %d type: %d\n", i, s->pict_type); |
455 | 1830 return best_fcode; |
324 | 1831 /* for(i=0; i<=MAX_FCODE; i++){ |
1832 printf("%d ", mv_num[i]); | |
1833 } | |
1834 printf("\n");*/ | |
1835 }else{ | |
1836 return 1; | |
0 | 1837 } |
1838 } | |
1839 | |
324 | 1840 void ff_fix_long_p_mvs(MpegEncContext * s) |
1841 { | |
1842 const int f_code= s->f_code; | |
1086 | 1843 int y, range; |
1421 | 1844 assert(s->pict_type==P_TYPE); |
1086 | 1845 |
1421 | 1846 range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); |
1086 | 1847 |
1848 if(s->msmpeg4_version) range= 16; | |
1849 | |
1850 if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range; | |
1851 | |
455 | 1852 //printf("%d no:%d %d//\n", clip, noclip, f_code); |
324 | 1853 if(s->flags&CODEC_FLAG_4MV){ |
1854 const int wrap= 2+ s->mb_width*2; | |
1855 | |
1856 /* clip / convert to intra 8x8 type MVs */ | |
1857 for(y=0; y<s->mb_height; y++){ | |
1858 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
|
1859 int i= y*s->mb_stride; |
324 | 1860 int x; |
1861 | |
1862 for(x=0; x<s->mb_width; x++){ | |
1708 | 1863 if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){ |
324 | 1864 int block; |
1865 for(block=0; block<4; block++){ | |
1866 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
|
1867 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
|
1868 int my= s->current_picture.motion_val[0][ xy + off ][1]; |
324 | 1869 |
1086 | 1870 if( mx >=range || mx <-range |
1871 || my >=range || my <-range){ | |
1708 | 1872 s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V; |
1873 s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA; | |
1874 s->current_picture.mb_type[i]= CANDIDATE_MB_TYPE_INTRA; | |
324 | 1875 } |
1876 } | |
1877 } | |
502 | 1878 xy+=2; |
1879 i++; | |
324 | 1880 } |
1881 } | |
1882 } | |
1883 } | |
1884 | |
1708 | 1885 /** |
1886 * | |
1887 * @param truncate 1 for truncation, 0 for using intra | |
1888 */ | |
1889 void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, | |
1890 int16_t (*mv_table)[2], int f_code, int type, int truncate) | |
324 | 1891 { |
1708 | 1892 int y, h_range, v_range; |
324 | 1893 |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1894 // RAL: 8 in MPEG-1, 16 in MPEG-4 |
1421 | 1895 int range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); |
1708 | 1896 |
1897 if(s->msmpeg4_version) range= 16; | |
1086 | 1898 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
|
1899 |
1708 | 1900 h_range= range; |
1901 v_range= field_select_table ? range>>1 : range; | |
1902 | |
324 | 1903 /* clip / convert to intra 16x16 type MVs */ |
1904 for(y=0; y<s->mb_height; y++){ | |
1905 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
|
1906 int xy= y*s->mb_stride; |
1086 | 1907 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
|
1908 if (s->mb_type[xy] & type){ // RAL: "type" test added... |
1708 | 1909 if(field_select_table==NULL || field_select_table[xy] == field_select){ |
1910 if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range | |
1911 || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){ | |
1086 | 1912 |
1708 | 1913 if(truncate){ |
1914 if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1; | |
1915 else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range; | |
1916 if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1; | |
1917 else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range; | |
1918 }else{ | |
1919 s->mb_type[xy] &= ~type; | |
1920 s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA; | |
1921 mv_table[xy][0]= | |
1922 mv_table[xy][1]= 0; | |
1923 } | |
1051
e5a9dbf597d4
mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me
michaelni
parents:
1050
diff
changeset
|
1924 } |
1086 | 1925 } |
324 | 1926 } |
1927 xy++; | |
1928 } | |
1929 } | |
1930 } |