Mercurial > libavcodec.hg
annotate motion_est_template.c @ 3308:57078a058b96 libavcodec
fix compilation of 3dnowext instinsincs, both on ia32 and AMD64.
3dnow intrinsincs are for now only compiled if 3dnowext support is available. (I should add smth that
checks for plain 3dnow later)
author | gpoirier |
---|---|
date | Tue, 16 May 2006 14:24:45 +0000 |
parents | f1bcb9ae510b |
children | c8c591fe26f8 |
rev | line source |
---|---|
936 | 1 /* |
2967 | 2 * Motion estimation |
1739
07a484280a82
copyright year update of the files i touched and remembered, things look annoyingly unmaintained otherwise
michael
parents:
1708
diff
changeset
|
3 * Copyright (c) 2002-2004 Michael Niedermayer |
936 | 4 * |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
936 | 18 * |
19 */ | |
2967 | 20 |
1106 | 21 /** |
22 * @file motion_est_template.c | |
23 * Motion estimation template. | |
24 */ | |
1950 | 25 |
936 | 26 //lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...) |
1708 | 27 #define LOAD_COMMON\ |
2522
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2327
diff
changeset
|
28 uint32_t attribute_unused * const score_map= c->score_map;\ |
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2327
diff
changeset
|
29 const int attribute_unused xmin= c->xmin;\ |
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2327
diff
changeset
|
30 const int attribute_unused ymin= c->ymin;\ |
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2327
diff
changeset
|
31 const int attribute_unused xmax= c->xmax;\ |
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2327
diff
changeset
|
32 const int attribute_unused ymax= c->ymax;\ |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
33 uint8_t *mv_penalty= c->current_mv_penalty;\ |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
34 const int pred_x= c->pred_x;\ |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
35 const int pred_y= c->pred_y;\ |
936 | 36 |
37 #define CHECK_HALF_MV(dx, dy, x, y)\ | |
38 {\ | |
39 const int hx= 2*(x)+(dx);\ | |
40 const int hy= 2*(y)+(dy);\ | |
1950 | 41 d= cmp(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\ |
936 | 42 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\ |
43 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\ | |
44 } | |
45 | |
46 #if 0 | |
1950 | 47 static int hpel_motion_search)(MpegEncContext * s, |
2979 | 48 int *mx_ptr, int *my_ptr, int dmin, |
2967 | 49 uint8_t *ref_data[3], |
1950 | 50 int size) |
936 | 51 { |
52 const int xx = 16 * s->mb_x + 8*(n&1); | |
53 const int yy = 16 * s->mb_y + 8*(n>>1); | |
54 const int mx = *mx_ptr; | |
55 const int my = *my_ptr; | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
56 const int penalty_factor= c->sub_penalty_factor; |
2967 | 57 |
1708 | 58 LOAD_COMMON |
2967 | 59 |
936 | 60 // INIT; |
61 //FIXME factorize | |
62 me_cmp_func cmp, chroma_cmp, cmp_sub, chroma_cmp_sub; | |
63 | |
64 if(s->no_rounding /*FIXME b_type*/){ | |
65 hpel_put= &s->dsp.put_no_rnd_pixels_tab[size]; | |
66 chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1]; | |
67 }else{ | |
68 hpel_put=& s->dsp.put_pixels_tab[size]; | |
69 chroma_hpel_put= &s->dsp.put_pixels_tab[size+1]; | |
70 } | |
1950 | 71 cmpf= s->dsp.me_cmp[size]; |
72 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
936 | 73 cmp_sub= s->dsp.me_sub_cmp[size]; |
74 chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; | |
75 | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
76 if(c->skip){ //FIXME somehow move up (benchmark) |
936 | 77 *mx_ptr = 0; |
78 *my_ptr = 0; | |
79 return dmin; | |
80 } | |
2967 | 81 |
2015
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
82 if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ |
936 | 83 CMP_HPEL(dmin, 0, 0, mx, my, size); |
84 if(mx || my) | |
85 dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor; | |
86 } | |
2967 | 87 |
88 if (mx > xmin && mx < xmax && | |
936 | 89 my > ymin && my < ymax) { |
90 int bx=2*mx, by=2*my; | |
91 int d= dmin; | |
2967 | 92 |
936 | 93 CHECK_HALF_MV(1, 1, mx-1, my-1) |
2967 | 94 CHECK_HALF_MV(0, 1, mx , my-1) |
936 | 95 CHECK_HALF_MV(1, 1, mx , my-1) |
96 CHECK_HALF_MV(1, 0, mx-1, my ) | |
97 CHECK_HALF_MV(1, 0, mx , my ) | |
98 CHECK_HALF_MV(1, 1, mx-1, my ) | |
2967 | 99 CHECK_HALF_MV(0, 1, mx , my ) |
936 | 100 CHECK_HALF_MV(1, 1, mx , my ) |
101 | |
948 | 102 assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2); |
936 | 103 |
104 *mx_ptr = bx; | |
105 *my_ptr = by; | |
106 }else{ | |
107 *mx_ptr =2*mx; | |
108 *my_ptr =2*my; | |
109 } | |
110 | |
111 return dmin; | |
112 } | |
113 | |
114 #else | |
1950 | 115 static int hpel_motion_search(MpegEncContext * s, |
2979 | 116 int *mx_ptr, int *my_ptr, int dmin, |
1950 | 117 int src_index, int ref_index, |
118 int size, int h) | |
936 | 119 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
120 MotionEstContext * const c= &s->me; |
936 | 121 const int mx = *mx_ptr; |
2967 | 122 const int my = *my_ptr; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
123 const int penalty_factor= c->sub_penalty_factor; |
936 | 124 me_cmp_func cmp_sub, chroma_cmp_sub; |
1013 | 125 int bx=2*mx, by=2*my; |
936 | 126 |
1708 | 127 LOAD_COMMON |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
128 int flags= c->sub_flags; |
2967 | 129 |
936 | 130 //FIXME factorize |
131 | |
132 cmp_sub= s->dsp.me_sub_cmp[size]; | |
133 chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; | |
134 | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
135 if(c->skip){ //FIXME move out of hpel? |
936 | 136 *mx_ptr = 0; |
137 *my_ptr = 0; | |
138 return dmin; | |
139 } | |
2967 | 140 |
2015
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
141 if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ |
1950 | 142 dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); |
1011 | 143 if(mx || my || size>0) |
936 | 144 dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor; |
145 } | |
2967 | 146 |
147 if (mx > xmin && mx < xmax && | |
936 | 148 my > ymin && my < ymax) { |
149 int d= dmin; | |
150 const int index= (my<<ME_MAP_SHIFT) + mx; | |
2967 | 151 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
152 + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor; |
936 | 153 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
154 + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor; |
936 | 155 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)] |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
156 + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor; |
936 | 157 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
158 + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor; |
2967 | 159 |
1013 | 160 #if 1 |
948 | 161 int key; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
162 int map_generation= c->map_generation; |
1419 | 163 #ifndef NDEBUG |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
164 uint32_t *map= c->map; |
1419 | 165 #endif |
948 | 166 key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation; |
167 assert(map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); | |
168 key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation; | |
169 assert(map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); | |
170 key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation; | |
171 assert(map[(index+1)&(ME_MAP_SIZE-1)] == key); | |
172 key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation; | |
173 assert(map[(index-1)&(ME_MAP_SIZE-1)] == key); | |
2967 | 174 #endif |
936 | 175 if(t<=b){ |
176 CHECK_HALF_MV(0, 1, mx ,my-1) | |
177 if(l<=r){ | |
178 CHECK_HALF_MV(1, 1, mx-1, my-1) | |
179 if(t+r<=b+l){ | |
180 CHECK_HALF_MV(1, 1, mx , my-1) | |
181 }else{ | |
182 CHECK_HALF_MV(1, 1, mx-1, my ) | |
183 } | |
184 CHECK_HALF_MV(1, 0, mx-1, my ) | |
185 }else{ | |
186 CHECK_HALF_MV(1, 1, mx , my-1) | |
187 if(t+l<=b+r){ | |
188 CHECK_HALF_MV(1, 1, mx-1, my-1) | |
189 }else{ | |
190 CHECK_HALF_MV(1, 1, mx , my ) | |
191 } | |
192 CHECK_HALF_MV(1, 0, mx , my ) | |
193 } | |
194 }else{ | |
195 if(l<=r){ | |
196 if(t+l<=b+r){ | |
197 CHECK_HALF_MV(1, 1, mx-1, my-1) | |
198 }else{ | |
199 CHECK_HALF_MV(1, 1, mx , my ) | |
200 } | |
201 CHECK_HALF_MV(1, 0, mx-1, my) | |
202 CHECK_HALF_MV(1, 1, mx-1, my) | |
203 }else{ | |
204 if(t+r<=b+l){ | |
205 CHECK_HALF_MV(1, 1, mx , my-1) | |
206 }else{ | |
207 CHECK_HALF_MV(1, 1, mx-1, my) | |
208 } | |
209 CHECK_HALF_MV(1, 0, mx , my) | |
210 CHECK_HALF_MV(1, 1, mx , my) | |
211 } | |
212 CHECK_HALF_MV(0, 1, mx , my) | |
213 } | |
214 assert(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2); | |
215 } | |
216 | |
1013 | 217 *mx_ptr = bx; |
218 *my_ptr = by; | |
2967 | 219 |
936 | 220 return dmin; |
221 } | |
222 #endif | |
223 | |
2327
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
224 static int no_sub_motion_search(MpegEncContext * s, |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
225 int *mx_ptr, int *my_ptr, int dmin, |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
226 int src_index, int ref_index, |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
227 int size, int h) |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
228 { |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
229 (*mx_ptr)<<=1; |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
230 (*my_ptr)<<=1; |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
231 return dmin; |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
232 } |
5e5cf598a48b
H.261 encoder by (Maarten Daniels <maarten dot daniels at luc dot ac dot be>)
michael
parents:
2226
diff
changeset
|
233 |
2189
70b27300a496
quad tree based motion compensation (currently only 16x16 & 8x8 OBMC blocks, but can be extended to other block sizes easily)
michael
parents:
2184
diff
changeset
|
234 int inline ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, |
70b27300a496
quad tree based motion compensation (currently only 16x16 & 8x8 OBMC blocks, but can be extended to other block sizes easily)
michael
parents:
2184
diff
changeset
|
235 int ref_index, int size, int h, int add_rate) |
1013 | 236 { |
237 // const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp; | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
238 MotionEstContext * const c= &s->me; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
239 const int penalty_factor= c->mb_penalty_factor; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
240 const int flags= c->mb_flags; |
1950 | 241 const int qpel= flags & FLAG_QPEL; |
242 const int mask= 1+2*qpel; | |
1013 | 243 me_cmp_func cmp_sub, chroma_cmp_sub; |
244 int d; | |
245 | |
1708 | 246 LOAD_COMMON |
2967 | 247 |
1013 | 248 //FIXME factorize |
249 | |
250 cmp_sub= s->dsp.mb_cmp[size]; | |
251 chroma_cmp_sub= s->dsp.mb_cmp[size+1]; | |
2967 | 252 |
2189
70b27300a496
quad tree based motion compensation (currently only 16x16 & 8x8 OBMC blocks, but can be extended to other block sizes easily)
michael
parents:
2184
diff
changeset
|
253 // assert(!c->skip); |
70b27300a496
quad tree based motion compensation (currently only 16x16 & 8x8 OBMC blocks, but can be extended to other block sizes easily)
michael
parents:
2184
diff
changeset
|
254 // assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp); |
1013 | 255 |
1950 | 256 d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); |
1013 | 257 //FIXME check cbp before adding penalty for (0,0) vector |
2189
70b27300a496
quad tree based motion compensation (currently only 16x16 & 8x8 OBMC blocks, but can be extended to other block sizes easily)
michael
parents:
2184
diff
changeset
|
258 if(add_rate && (mx || my || size>0)) |
1013 | 259 d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor; |
2967 | 260 |
1013 | 261 return d; |
262 } | |
263 | |
936 | 264 #define CHECK_QUARTER_MV(dx, dy, x, y)\ |
265 {\ | |
266 const int hx= 4*(x)+(dx);\ | |
267 const int hy= 4*(y)+(dy);\ | |
1950 | 268 d= cmp(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ |
936 | 269 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\ |
270 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\ | |
271 } | |
272 | |
1950 | 273 static int qpel_motion_search(MpegEncContext * s, |
2979 | 274 int *mx_ptr, int *my_ptr, int dmin, |
2967 | 275 int src_index, int ref_index, |
1950 | 276 int size, int h) |
936 | 277 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
278 MotionEstContext * const c= &s->me; |
936 | 279 const int mx = *mx_ptr; |
2967 | 280 const int my = *my_ptr; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
281 const int penalty_factor= c->sub_penalty_factor; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
282 const int map_generation= c->map_generation; |
2015
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
283 const int subpel_quality= c->avctx->me_subpel_quality; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
284 uint32_t *map= c->map; |
1950 | 285 me_cmp_func cmpf, chroma_cmpf; |
936 | 286 me_cmp_func cmp_sub, chroma_cmp_sub; |
287 | |
1708 | 288 LOAD_COMMON |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
289 int flags= c->sub_flags; |
2967 | 290 |
1950 | 291 cmpf= s->dsp.me_cmp[size]; |
292 chroma_cmpf= s->dsp.me_cmp[size+1]; //factorize FIXME | |
936 | 293 //FIXME factorize |
294 | |
295 cmp_sub= s->dsp.me_sub_cmp[size]; | |
296 chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; | |
297 | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
298 if(c->skip){ //FIXME somehow move up (benchmark) |
936 | 299 *mx_ptr = 0; |
300 *my_ptr = 0; | |
301 return dmin; | |
302 } | |
2967 | 303 |
2015
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
304 if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ |
1950 | 305 dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); |
1011 | 306 if(mx || my || size>0) |
936 | 307 dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor; |
308 } | |
2967 | 309 |
310 if (mx > xmin && mx < xmax && | |
936 | 311 my > ymin && my < ymax) { |
312 int bx=4*mx, by=4*my; | |
313 int d= dmin; | |
314 int i, nx, ny; | |
315 const int index= (my<<ME_MAP_SHIFT) + mx; | |
316 const int t= score_map[(index-(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)]; | |
317 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]; | |
318 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]; | |
319 const int b= score_map[(index+(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)]; | |
320 const int c= score_map[(index )&(ME_MAP_SIZE-1)]; | |
321 int best[8]; | |
322 int best_pos[8][2]; | |
2967 | 323 |
936 | 324 memset(best, 64, sizeof(int)*8); |
325 #if 1 | |
2967 | 326 if(s->me.dia_size>=2){ |
936 | 327 const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; |
328 const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; | |
329 const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)]; | |
330 const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)]; | |
331 | |
332 for(ny= -3; ny <= 3; ny++){ | |
333 for(nx= -3; nx <= 3; nx++){ | |
2079 | 334 //FIXME this could overflow (unlikely though) |
335 const int64_t t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t; | |
336 const int64_t c2= nx*nx*( r + l - 2*c) + 4*nx*( r- l) + 32*c; | |
337 const int64_t b2= nx*nx*(br + bl - 2*b) + 4*nx*(br-bl) + 32*b; | |
338 int score= (ny*ny*(b2 + t2 - 2*c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10; | |
936 | 339 int i; |
2967 | 340 |
936 | 341 if((nx&3)==0 && (ny&3)==0) continue; |
2967 | 342 |
2079 | 343 score += (mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor; |
2967 | 344 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
345 // if(nx&1) score-=1024*c->penalty_factor; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
346 // if(ny&1) score-=1024*c->penalty_factor; |
2967 | 347 |
936 | 348 for(i=0; i<8; i++){ |
349 if(score < best[i]){ | |
350 memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); | |
351 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); | |
352 best[i]= score; | |
353 best_pos[i][0]= nx + 4*mx; | |
354 best_pos[i][1]= ny + 4*my; | |
355 break; | |
356 } | |
357 } | |
358 } | |
359 } | |
360 }else{ | |
361 int tl; | |
2079 | 362 //FIXME this could overflow (unlikely though) |
936 | 363 const int cx = 4*(r - l); |
2967 | 364 const int cx2= r + l - 2*c; |
936 | 365 const int cy = 4*(b - t); |
366 const int cy2= b + t - 2*c; | |
367 int cxy; | |
2967 | 368 |
936 | 369 if(map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)] == (my<<ME_MAP_MV_BITS) + mx + map_generation && 0){ //FIXME |
370 tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; | |
371 }else{ | |
1950 | 372 tl= cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);//FIXME wrong if chroma me is different |
936 | 373 } |
2967 | 374 |
375 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*c; | |
376 | |
936 | 377 assert(16*cx2 + 4*cx + 32*c == 32*r); |
378 assert(16*cx2 - 4*cx + 32*c == 32*l); | |
379 assert(16*cy2 + 4*cy + 32*c == 32*b); | |
380 assert(16*cy2 - 4*cy + 32*c == 32*t); | |
381 assert(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl); | |
2967 | 382 |
936 | 383 for(ny= -3; ny <= 3; ny++){ |
384 for(nx= -3; nx <= 3; nx++){ | |
2079 | 385 //FIXME this could overflow (unlikely though) |
936 | 386 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*c; //FIXME factor |
387 int i; | |
2967 | 388 |
936 | 389 if((nx&3)==0 && (ny&3)==0) continue; |
2967 | 390 |
936 | 391 score += 32*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
392 // if(nx&1) score-=32*c->penalty_factor; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
393 // if(ny&1) score-=32*c->penalty_factor; |
2967 | 394 |
936 | 395 for(i=0; i<8; i++){ |
396 if(score < best[i]){ | |
397 memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); | |
398 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); | |
399 best[i]= score; | |
400 best_pos[i][0]= nx + 4*mx; | |
401 best_pos[i][1]= ny + 4*my; | |
402 break; | |
403 } | |
404 } | |
405 } | |
2967 | 406 } |
936 | 407 } |
954 | 408 for(i=0; i<subpel_quality; i++){ |
936 | 409 nx= best_pos[i][0]; |
410 ny= best_pos[i][1]; | |
411 CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2) | |
412 } | |
954 | 413 |
936 | 414 #if 0 |
954 | 415 const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; |
416 const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; | |
417 const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)]; | |
418 const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)]; | |
419 // if(l < r && l < t && l < b && l < tl && l < bl && l < tr && l < br && bl < tl){ | |
420 if(tl<br){ | |
421 | |
422 // nx= FFMAX(4*mx - bx, bx - 4*mx); | |
423 // ny= FFMAX(4*my - by, by - 4*my); | |
2967 | 424 |
954 | 425 static int stats[7][7], count; |
426 count++; | |
427 stats[4*mx - bx + 3][4*my - by + 3]++; | |
428 if(256*256*256*64 % count ==0){ | |
429 for(i=0; i<49; i++){ | |
430 if((i%7)==0) printf("\n"); | |
936 | 431 printf("%6d ", stats[0][i]); |
432 } | |
433 printf("\n"); | |
434 } | |
954 | 435 } |
936 | 436 #endif |
437 #else | |
438 | |
439 CHECK_QUARTER_MV(2, 2, mx-1, my-1) | |
2967 | 440 CHECK_QUARTER_MV(0, 2, mx , my-1) |
936 | 441 CHECK_QUARTER_MV(2, 2, mx , my-1) |
442 CHECK_QUARTER_MV(2, 0, mx , my ) | |
443 CHECK_QUARTER_MV(2, 2, mx , my ) | |
444 CHECK_QUARTER_MV(0, 2, mx , my ) | |
445 CHECK_QUARTER_MV(2, 2, mx-1, my ) | |
446 CHECK_QUARTER_MV(2, 0, mx-1, my ) | |
2967 | 447 |
936 | 448 nx= bx; |
449 ny= by; | |
2967 | 450 |
936 | 451 for(i=0; i<8; i++){ |
452 int ox[8]= {0, 1, 1, 1, 0,-1,-1,-1}; | |
453 int oy[8]= {1, 1, 0,-1,-1,-1, 0, 1}; | |
454 CHECK_QUARTER_MV((nx + ox[i])&3, (ny + oy[i])&3, (nx + ox[i])>>2, (ny + oy[i])>>2) | |
455 } | |
456 #endif | |
457 #if 0 | |
458 //outer ring | |
459 CHECK_QUARTER_MV(1, 3, mx-1, my-1) | |
460 CHECK_QUARTER_MV(1, 2, mx-1, my-1) | |
461 CHECK_QUARTER_MV(1, 1, mx-1, my-1) | |
462 CHECK_QUARTER_MV(2, 1, mx-1, my-1) | |
463 CHECK_QUARTER_MV(3, 1, mx-1, my-1) | |
464 CHECK_QUARTER_MV(0, 1, mx , my-1) | |
465 CHECK_QUARTER_MV(1, 1, mx , my-1) | |
466 CHECK_QUARTER_MV(2, 1, mx , my-1) | |
467 CHECK_QUARTER_MV(3, 1, mx , my-1) | |
468 CHECK_QUARTER_MV(3, 2, mx , my-1) | |
469 CHECK_QUARTER_MV(3, 3, mx , my-1) | |
470 CHECK_QUARTER_MV(3, 0, mx , my ) | |
471 CHECK_QUARTER_MV(3, 1, mx , my ) | |
472 CHECK_QUARTER_MV(3, 2, mx , my ) | |
473 CHECK_QUARTER_MV(3, 3, mx , my ) | |
474 CHECK_QUARTER_MV(2, 3, mx , my ) | |
475 CHECK_QUARTER_MV(1, 3, mx , my ) | |
476 CHECK_QUARTER_MV(0, 3, mx , my ) | |
477 CHECK_QUARTER_MV(3, 3, mx-1, my ) | |
478 CHECK_QUARTER_MV(2, 3, mx-1, my ) | |
479 CHECK_QUARTER_MV(1, 3, mx-1, my ) | |
480 CHECK_QUARTER_MV(1, 2, mx-1, my ) | |
481 CHECK_QUARTER_MV(1, 1, mx-1, my ) | |
482 CHECK_QUARTER_MV(1, 0, mx-1, my ) | |
483 #endif | |
484 assert(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4); | |
485 | |
486 *mx_ptr = bx; | |
487 *my_ptr = by; | |
488 }else{ | |
489 *mx_ptr =4*mx; | |
490 *my_ptr =4*my; | |
491 } | |
492 | |
493 return dmin; | |
494 } | |
495 | |
496 | |
497 #define CHECK_MV(x,y)\ | |
498 {\ | |
499 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ | |
500 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ | |
2072 | 501 assert((x) >= xmin);\ |
502 assert((x) <= xmax);\ | |
503 assert((y) >= ymin);\ | |
504 assert((y) <= ymax);\ | |
948 | 505 /*printf("check_mv %d %d\n", x, y);*/\ |
936 | 506 if(map[index]!=key){\ |
1950 | 507 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ |
936 | 508 map[index]= key;\ |
509 score_map[index]= d;\ | |
510 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ | |
948 | 511 /*printf("score:%d\n", d);*/\ |
936 | 512 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\ |
513 }\ | |
514 } | |
515 | |
948 | 516 #define CHECK_CLIPED_MV(ax,ay)\ |
517 {\ | |
1799 | 518 const int x= ax;\ |
519 const int y= ay;\ | |
520 const int x2= FFMAX(xmin, FFMIN(x, xmax));\ | |
521 const int y2= FFMAX(ymin, FFMIN(y, ymax));\ | |
522 CHECK_MV(x2, y2)\ | |
948 | 523 } |
524 | |
936 | 525 #define CHECK_MV_DIR(x,y,new_dir)\ |
526 {\ | |
527 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ | |
528 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ | |
948 | 529 /*printf("check_mv_dir %d %d %d\n", x, y, new_dir);*/\ |
936 | 530 if(map[index]!=key){\ |
1950 | 531 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ |
936 | 532 map[index]= key;\ |
533 score_map[index]= d;\ | |
534 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ | |
948 | 535 /*printf("score:%d\n", d);*/\ |
936 | 536 if(d<dmin){\ |
537 best[0]=x;\ | |
538 best[1]=y;\ | |
539 dmin=d;\ | |
540 next_dir= new_dir;\ | |
541 }\ | |
542 }\ | |
543 } | |
544 | |
545 #define check(x,y,S,v)\ | |
546 if( (x)<(xmin<<(S)) ) printf("%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\ | |
547 if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\ | |
548 if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\ | |
549 if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\ | |
550 | |
1950 | 551 #define LOAD_COMMON2\ |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
552 uint32_t *map= c->map;\ |
1950 | 553 const int qpel= flags&FLAG_QPEL;\ |
554 const int shift= 1+qpel;\ | |
936 | 555 |
1950 | 556 static always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin, |
557 int src_index, int ref_index, int const penalty_factor, | |
558 int size, int h, int flags) | |
936 | 559 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
560 MotionEstContext * const c= &s->me; |
1950 | 561 me_cmp_func cmpf, chroma_cmpf; |
936 | 562 int next_dir=-1; |
1708 | 563 LOAD_COMMON |
1950 | 564 LOAD_COMMON2 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
565 int map_generation= c->map_generation; |
2967 | 566 |
1950 | 567 cmpf= s->dsp.me_cmp[size]; |
568 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
936 | 569 |
948 | 570 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */ |
571 const int key= (best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation; | |
572 const int index= ((best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1); | |
573 if(map[index]!=key){ //this will be executed only very rarey | |
1950 | 574 score_map[index]= cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags); |
948 | 575 map[index]= key; |
576 } | |
577 } | |
578 | |
936 | 579 for(;;){ |
580 int d; | |
581 const int dir= next_dir; | |
582 const int x= best[0]; | |
583 const int y= best[1]; | |
584 next_dir=-1; | |
585 | |
586 //printf("%d", dir); | |
587 if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y , 0) | |
588 if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1) | |
589 if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y , 2) | |
590 if(dir!=1 && y<ymax) CHECK_MV_DIR(x , y+1, 3) | |
591 | |
592 if(next_dir==-1){ | |
593 return dmin; | |
594 } | |
595 } | |
596 } | |
597 | |
1950 | 598 static int funny_diamond_search(MpegEncContext * s, int *best, int dmin, |
599 int src_index, int ref_index, int const penalty_factor, | |
600 int size, int h, int flags) | |
948 | 601 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
602 MotionEstContext * const c= &s->me; |
1950 | 603 me_cmp_func cmpf, chroma_cmpf; |
948 | 604 int dia_size; |
1708 | 605 LOAD_COMMON |
1950 | 606 LOAD_COMMON2 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
607 int map_generation= c->map_generation; |
2967 | 608 |
1950 | 609 cmpf= s->dsp.me_cmp[size]; |
610 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
948 | 611 |
612 for(dia_size=1; dia_size<=4; dia_size++){ | |
613 int dir; | |
614 const int x= best[0]; | |
615 const int y= best[1]; | |
2967 | 616 |
948 | 617 if(dia_size&(dia_size-1)) continue; |
618 | |
619 if( x + dia_size > xmax | |
620 || x - dia_size < xmin | |
621 || y + dia_size > ymax | |
622 || y - dia_size < ymin) | |
623 continue; | |
2967 | 624 |
948 | 625 for(dir= 0; dir<dia_size; dir+=2){ |
626 int d; | |
627 | |
628 CHECK_MV(x + dir , y + dia_size - dir); | |
629 CHECK_MV(x + dia_size - dir, y - dir ); | |
630 CHECK_MV(x - dir , y - dia_size + dir); | |
631 CHECK_MV(x - dia_size + dir, y + dir ); | |
632 } | |
633 | |
634 if(x!=best[0] || y!=best[1]) | |
635 dia_size=0; | |
636 #if 0 | |
637 { | |
638 int dx, dy, i; | |
639 static int stats[8*8]; | |
640 dx= ABS(x-best[0]); | |
641 dy= ABS(y-best[1]); | |
642 if(dy>dx){ | |
643 dx^=dy; dy^=dx; dx^=dy; | |
644 } | |
645 stats[dy*8 + dx] ++; | |
646 if(256*256*256*64 % (stats[0]+1)==0){ | |
647 for(i=0; i<64; i++){ | |
648 if((i&7)==0) printf("\n"); | |
649 printf("%8d ", stats[i]); | |
650 } | |
651 printf("\n"); | |
652 } | |
653 } | |
654 #endif | |
655 } | |
2967 | 656 return dmin; |
948 | 657 } |
658 | |
659 #define SAB_CHECK_MV(ax,ay)\ | |
660 {\ | |
661 const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\ | |
662 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\ | |
663 /*printf("sab check %d %d\n", ax, ay);*/\ | |
664 if(map[index]!=key){\ | |
1950 | 665 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ |
948 | 666 map[index]= key;\ |
667 score_map[index]= d;\ | |
668 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\ | |
669 /*printf("score: %d\n", d);*/\ | |
670 if(d < minima[minima_count-1].height){\ | |
671 int j=0;\ | |
672 \ | |
673 while(d >= minima[j].height) j++;\ | |
674 \ | |
675 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\ | |
676 \ | |
677 minima[j].checked= 0;\ | |
678 minima[j].height= d;\ | |
679 minima[j].x= ax;\ | |
680 minima[j].y= ay;\ | |
681 \ | |
682 i=-1;\ | |
683 continue;\ | |
684 }\ | |
685 }\ | |
686 } | |
687 | |
2113
07a663d46be2
shape-adaptive diamond + prediction crash patch by (Loren Merritt <lorenm at u dot washington dot edu>)
michael
parents:
2079
diff
changeset
|
688 #define MAX_SAB_SIZE ME_MAP_SIZE |
1950 | 689 static int sab_diamond_search(MpegEncContext * s, int *best, int dmin, |
690 int src_index, int ref_index, int const penalty_factor, | |
691 int size, int h, int flags) | |
948 | 692 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
693 MotionEstContext * const c= &s->me; |
1950 | 694 me_cmp_func cmpf, chroma_cmpf; |
948 | 695 Minima minima[MAX_SAB_SIZE]; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
696 const int minima_count= ABS(c->dia_size); |
948 | 697 int i, j; |
1708 | 698 LOAD_COMMON |
1950 | 699 LOAD_COMMON2 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
700 int map_generation= c->map_generation; |
2967 | 701 |
1950 | 702 cmpf= s->dsp.me_cmp[size]; |
703 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
2967 | 704 |
948 | 705 for(j=i=0; i<ME_MAP_SIZE; i++){ |
706 uint32_t key= map[i]; | |
707 | |
708 key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1)); | |
2967 | 709 |
948 | 710 if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue; |
2967 | 711 |
948 | 712 assert(j<MAX_SAB_SIZE); //max j = number of predictors |
2967 | 713 |
948 | 714 minima[j].height= score_map[i]; |
715 minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS; | |
716 minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1); | |
717 minima[j].x-= (1<<(ME_MAP_MV_BITS-1)); | |
718 minima[j].y-= (1<<(ME_MAP_MV_BITS-1)); | |
719 minima[j].checked=0; | |
720 if(minima[j].x || minima[j].y) | |
721 minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor; | |
2967 | 722 |
948 | 723 j++; |
724 } | |
2967 | 725 |
948 | 726 qsort(minima, j, sizeof(Minima), minima_cmp); |
2967 | 727 |
948 | 728 for(; j<minima_count; j++){ |
729 minima[j].height=256*256*256*64; | |
730 minima[j].checked=0; | |
731 minima[j].x= minima[j].y=0; | |
732 } | |
2967 | 733 |
948 | 734 for(i=0; i<minima_count; i++){ |
735 const int x= minima[i].x; | |
736 const int y= minima[i].y; | |
737 int d; | |
2967 | 738 |
948 | 739 if(minima[i].checked) continue; |
2967 | 740 |
948 | 741 if( x >= xmax || x <= xmin |
742 || y >= ymax || y <= ymin) | |
743 continue; | |
744 | |
745 SAB_CHECK_MV(x-1, y) | |
746 SAB_CHECK_MV(x+1, y) | |
747 SAB_CHECK_MV(x , y-1) | |
748 SAB_CHECK_MV(x , y+1) | |
2967 | 749 |
948 | 750 minima[i].checked= 1; |
751 } | |
2967 | 752 |
948 | 753 best[0]= minima[0].x; |
754 best[1]= minima[0].y; | |
755 dmin= minima[0].height; | |
2967 | 756 |
948 | 757 if( best[0] < xmax && best[0] > xmin |
758 && best[1] < ymax && best[1] > ymin){ | |
759 int d; | |
760 //ensure that the refernece samples for hpel refinement are in the map | |
761 CHECK_MV(best[0]-1, best[1]) | |
762 CHECK_MV(best[0]+1, best[1]) | |
763 CHECK_MV(best[0], best[1]-1) | |
764 CHECK_MV(best[0], best[1]+1) | |
765 } | |
2967 | 766 return dmin; |
948 | 767 } |
768 | |
1950 | 769 static int var_diamond_search(MpegEncContext * s, int *best, int dmin, |
770 int src_index, int ref_index, int const penalty_factor, | |
771 int size, int h, int flags) | |
936 | 772 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
773 MotionEstContext * const c= &s->me; |
1950 | 774 me_cmp_func cmpf, chroma_cmpf; |
948 | 775 int dia_size; |
1708 | 776 LOAD_COMMON |
1950 | 777 LOAD_COMMON2 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
778 int map_generation= c->map_generation; |
2967 | 779 |
1950 | 780 cmpf= s->dsp.me_cmp[size]; |
781 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
936 | 782 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
783 for(dia_size=1; dia_size<=c->dia_size; dia_size++){ |
936 | 784 int dir, start, end; |
785 const int x= best[0]; | |
786 const int y= best[1]; | |
787 | |
788 start= FFMAX(0, y + dia_size - ymax); | |
948 | 789 end = FFMIN(dia_size, xmax - x + 1); |
936 | 790 for(dir= start; dir<end; dir++){ |
791 int d; | |
792 | |
793 //check(x + dir,y + dia_size - dir,0, a0) | |
794 CHECK_MV(x + dir , y + dia_size - dir); | |
795 } | |
796 | |
797 start= FFMAX(0, x + dia_size - xmax); | |
948 | 798 end = FFMIN(dia_size, y - ymin + 1); |
936 | 799 for(dir= start; dir<end; dir++){ |
800 int d; | |
801 | |
802 //check(x + dia_size - dir, y - dir,0, a1) | |
803 CHECK_MV(x + dia_size - dir, y - dir ); | |
804 } | |
805 | |
806 start= FFMAX(0, -y + dia_size + ymin ); | |
948 | 807 end = FFMIN(dia_size, x - xmin + 1); |
936 | 808 for(dir= start; dir<end; dir++){ |
809 int d; | |
810 | |
811 //check(x - dir,y - dia_size + dir,0, a2) | |
812 CHECK_MV(x - dir , y - dia_size + dir); | |
813 } | |
814 | |
815 start= FFMAX(0, -x + dia_size + xmin ); | |
948 | 816 end = FFMIN(dia_size, ymax - y + 1); |
936 | 817 for(dir= start; dir<end; dir++){ |
818 int d; | |
819 | |
820 //check(x - dia_size + dir, y + dir,0, a3) | |
821 CHECK_MV(x - dia_size + dir, y + dir ); | |
822 } | |
823 | |
824 if(x!=best[0] || y!=best[1]) | |
825 dia_size=0; | |
948 | 826 #if 0 |
827 { | |
828 int dx, dy, i; | |
829 static int stats[8*8]; | |
830 dx= ABS(x-best[0]); | |
831 dy= ABS(y-best[1]); | |
832 stats[dy*8 + dx] ++; | |
833 if(256*256*256*64 % (stats[0]+1)==0){ | |
834 for(i=0; i<64; i++){ | |
835 if((i&7)==0) printf("\n"); | |
836 printf("%6d ", stats[i]); | |
837 } | |
838 printf("\n"); | |
839 } | |
840 } | |
841 #endif | |
936 | 842 } |
2967 | 843 return dmin; |
936 | 844 } |
845 | |
1950 | 846 static always_inline int diamond_search(MpegEncContext * s, int *best, int dmin, |
847 int src_index, int ref_index, int const penalty_factor, | |
848 int size, int h, int flags){ | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
849 MotionEstContext * const c= &s->me; |
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
850 if(c->dia_size==-1) |
1950 | 851 return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
852 else if(c->dia_size<-1) |
1950 | 853 return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
854 else if(c->dia_size<2) |
1950 | 855 return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
856 else | |
857 return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); | |
858 } | |
859 | |
860 static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx_ptr, int *my_ptr, | |
2967 | 861 int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], |
2184 | 862 int ref_mv_scale, int flags, int size, int h) |
936 | 863 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
864 MotionEstContext * const c= &s->me; |
936 | 865 int best[2]={0, 0}; |
1950 | 866 int d, dmin; |
936 | 867 int map_generation; |
2226 | 868 int penalty_factor; |
1708 | 869 const int ref_mv_stride= s->mb_stride; //pass as arg FIXME |
870 const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME | |
1950 | 871 me_cmp_func cmpf, chroma_cmpf; |
2967 | 872 |
1950 | 873 LOAD_COMMON |
874 LOAD_COMMON2 | |
2967 | 875 |
2226 | 876 if(c->pre_pass){ |
877 penalty_factor= c->pre_penalty_factor; | |
878 cmpf= s->dsp.me_pre_cmp[size]; | |
879 chroma_cmpf= s->dsp.me_pre_cmp[size+1]; | |
880 }else{ | |
881 penalty_factor= c->penalty_factor; | |
882 cmpf= s->dsp.me_cmp[size]; | |
883 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
884 } | |
2967 | 885 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
886 map_generation= update_map_generation(c); |
936 | 887 |
2184 | 888 assert(cmpf); |
1950 | 889 dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags); |
936 | 890 map[0]= map_generation; |
891 score_map[0]= dmin; | |
892 | |
893 /* first line */ | |
1799 | 894 if (s->first_slice_line) { |
936 | 895 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
2967 | 896 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
948 | 897 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
936 | 898 }else{ |
3293 | 899 if(dmin<((h*h*s->avctx->mv0_threshold)>>8) |
900 && ( P_LEFT[0] |P_LEFT[1] | |
936 | 901 |P_TOP[0] |P_TOP[1] |
948 | 902 |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){ |
936 | 903 *mx_ptr= 0; |
904 *my_ptr= 0; | |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
905 c->skip=1; |
936 | 906 return dmin; |
907 } | |
908 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) | |
2184 | 909 if(dmin>h*h*2){ |
2967 | 910 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
948 | 911 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
936 | 912 CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) |
913 CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) | |
914 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) | |
915 } | |
916 } | |
2184 | 917 if(dmin>h*h*4){ |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
918 if(c->pre_pass){ |
2967 | 919 CHECK_CLIPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16, |
952 | 920 (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16) |
1799 | 921 if(!s->first_slice_line) |
2967 | 922 CHECK_CLIPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
1799 | 923 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
952 | 924 }else{ |
2967 | 925 CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, |
952 | 926 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) |
1800
e039d79185c2
simplify MV availability check / dont use below last row MV which is always zero
michael
parents:
1799
diff
changeset
|
927 if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line |
2967 | 928 CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
1799 | 929 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
952 | 930 } |
936 | 931 } |
948 | 932 |
2015
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
933 if(c->avctx->last_predictor_count){ |
3ab8f3e2ae6a
moving motion estimation specific variables from MpegEncContext -> MotionEstContext
michael
parents:
2014
diff
changeset
|
934 const int count= c->avctx->last_predictor_count; |
948 | 935 const int xstart= FFMAX(0, s->mb_x - count); |
936 const int ystart= FFMAX(0, s->mb_y - count); | |
937 const int xend= FFMIN(s->mb_width , s->mb_x + count + 1); | |
938 const int yend= FFMIN(s->mb_height, s->mb_y + count + 1); | |
939 int mb_y; | |
936 | 940 |
948 | 941 for(mb_y=ystart; mb_y<yend; mb_y++){ |
942 int mb_x; | |
943 for(mb_x=xstart; mb_x<xend; mb_x++){ | |
944 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride; | |
945 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16; | |
946 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16; | |
947 | |
948 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue; | |
949 CHECK_MV(mx,my) | |
936 | 950 } |
951 } | |
952 } | |
948 | 953 |
936 | 954 //check(best[0],best[1],0, b0) |
1950 | 955 dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
936 | 956 |
957 //check(best[0],best[1],0, b1) | |
958 *mx_ptr= best[0]; | |
2967 | 959 *my_ptr= best[1]; |
936 | 960 |
961 // printf("%d %d %d \n", best[0], best[1], dmin); | |
962 return dmin; | |
963 } | |
964 | |
1950 | 965 //this function is dedicated to the braindamaged gcc |
2184 | 966 inline int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, |
2967 | 967 int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], |
2184 | 968 int ref_mv_scale, int size, int h) |
1950 | 969 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
970 MotionEstContext * const c= &s->me; |
1950 | 971 //FIXME convert other functions in the same way if faster |
2184 | 972 if(c->flags==0 && h==16 && size==0){ |
973 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16); | |
1950 | 974 // case FLAG_QPEL: |
975 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL); | |
2184 | 976 }else{ |
977 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->flags, size, h); | |
1950 | 978 } |
979 } | |
980 | |
981 static int epzs_motion_search4(MpegEncContext * s, | |
982 int *mx_ptr, int *my_ptr, int P[10][2], | |
2967 | 983 int src_index, int ref_index, int16_t (*last_mv)[2], |
1950 | 984 int ref_mv_scale) |
936 | 985 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
986 MotionEstContext * const c= &s->me; |
936 | 987 int best[2]={0, 0}; |
2967 | 988 int d, dmin; |
936 | 989 int map_generation; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
990 const int penalty_factor= c->penalty_factor; |
936 | 991 const int size=1; |
1708 | 992 const int h=8; |
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
|
993 const int ref_mv_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
|
994 const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; |
1950 | 995 me_cmp_func cmpf, chroma_cmpf; |
1708 | 996 LOAD_COMMON |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
997 int flags= c->flags; |
1950 | 998 LOAD_COMMON2 |
2967 | 999 |
1950 | 1000 cmpf= s->dsp.me_cmp[size]; |
1001 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
936 | 1002 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
1003 map_generation= update_map_generation(c); |
936 | 1004 |
1005 dmin = 1000000; | |
2967 | 1006 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax); |
936 | 1007 /* first line */ |
1799 | 1008 if (s->first_slice_line) { |
2979 | 1009 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
2967 | 1010 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
948 | 1011 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
936 | 1012 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) |
1013 }else{ | |
1014 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) | |
1015 //FIXME try some early stop | |
1016 if(dmin>64*2){ | |
1017 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) | |
1018 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) | |
1019 CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) | |
1020 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) | |
2967 | 1021 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
948 | 1022 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
936 | 1023 } |
1024 } | |
1025 if(dmin>64*4){ | |
2967 | 1026 CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, |
948 | 1027 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) |
1800
e039d79185c2
simplify MV availability check / dont use below last row MV which is always zero
michael
parents:
1799
diff
changeset
|
1028 if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line |
2967 | 1029 CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
1799 | 1030 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
936 | 1031 } |
1032 | |
1950 | 1033 dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
1708 | 1034 |
1035 *mx_ptr= best[0]; | |
2967 | 1036 *my_ptr= best[1]; |
1708 | 1037 |
1038 // printf("%d %d %d \n", best[0], best[1], dmin); | |
1039 return dmin; | |
1040 } | |
1041 | |
1042 //try to merge with above FIXME (needs PSNR test) | |
1950 | 1043 static int epzs_motion_search2(MpegEncContext * s, |
1044 int *mx_ptr, int *my_ptr, int P[10][2], | |
2967 | 1045 int src_index, int ref_index, int16_t (*last_mv)[2], |
1950 | 1046 int ref_mv_scale) |
1708 | 1047 { |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
1048 MotionEstContext * const c= &s->me; |
1708 | 1049 int best[2]={0, 0}; |
2967 | 1050 int d, dmin; |
1708 | 1051 int map_generation; |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
1052 const int penalty_factor= c->penalty_factor; |
1708 | 1053 const int size=0; //FIXME pass as arg |
1054 const int h=8; | |
1055 const int ref_mv_stride= s->mb_stride; | |
1056 const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; | |
1950 | 1057 me_cmp_func cmpf, chroma_cmpf; |
1708 | 1058 LOAD_COMMON |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
1059 int flags= c->flags; |
1950 | 1060 LOAD_COMMON2 |
2967 | 1061 |
1950 | 1062 cmpf= s->dsp.me_cmp[size]; |
1063 chroma_cmpf= s->dsp.me_cmp[size+1]; | |
1708 | 1064 |
2014
15c885db82a8
reduce dependancy between motion estimation and MpegEncContext
michael
parents:
1950
diff
changeset
|
1065 map_generation= update_map_generation(c); |
1708 | 1066 |
1067 dmin = 1000000; | |
2967 | 1068 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax); |
1708 | 1069 /* first line */ |
1799 | 1070 if (s->first_slice_line) { |
2979 | 1071 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
2967 | 1072 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
1708 | 1073 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
1074 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) | |
1075 }else{ | |
1076 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) | |
1077 //FIXME try some early stop | |
1078 if(dmin>64*2){ | |
1079 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) | |
1080 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) | |
1081 CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) | |
1082 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) | |
2967 | 1083 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
1708 | 1084 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) |
1085 } | |
1086 } | |
1087 if(dmin>64*4){ | |
2967 | 1088 CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, |
1708 | 1089 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) |
1800
e039d79185c2
simplify MV availability check / dont use below last row MV which is always zero
michael
parents:
1799
diff
changeset
|
1090 if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line |
2967 | 1091 CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
1799 | 1092 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
1708 | 1093 } |
1094 | |
1950 | 1095 dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); |
948 | 1096 |
936 | 1097 *mx_ptr= best[0]; |
2967 | 1098 *my_ptr= best[1]; |
936 | 1099 |
1100 // printf("%d %d %d \n", best[0], best[1], dmin); | |
1101 return dmin; | |
1102 } |