FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/motion_est_template.c
Date: 2021-09-26 18:22:30
Exec Total Coverage
Lines: 311 498 62.4%
Branches: 228 490 46.5%

Line Branch Exec Source
1 /*
2 * Motion estimation
3 * Copyright (c) 2002-2004 Michael Niedermayer
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg 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.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * Motion estimation template.
25 */
26
27 #include "libavutil/qsort.h"
28 #include "mpegvideo.h"
29
30 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
31 #define LOAD_COMMON\
32 uint32_t av_unused * const score_map= c->score_map;\
33 const int av_unused xmin= c->xmin;\
34 const int av_unused ymin= c->ymin;\
35 const int av_unused xmax= c->xmax;\
36 const int av_unused ymax= c->ymax;\
37 const uint8_t *mv_penalty = c->current_mv_penalty; \
38 const int pred_x= c->pred_x;\
39 const int pred_y= c->pred_y;\
40
41 #define CHECK_HALF_MV(dx, dy, x, y)\
42 {\
43 const int hx= 2*(x)+(dx);\
44 const int hy= 2*(y)+(dy);\
45 d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\
46 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
47 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
48 }
49
50 597890 static int hpel_motion_search(MpegEncContext * s,
51 int *mx_ptr, int *my_ptr, int dmin,
52 int src_index, int ref_index,
53 int size, int h)
54 {
55 597890 MotionEstContext * const c= &s->me;
56 597890 const int mx = *mx_ptr;
57 597890 const int my = *my_ptr;
58 597890 const int penalty_factor= c->sub_penalty_factor;
59 me_cmp_func cmp_sub, chroma_cmp_sub;
60 597890 int bx=2*mx, by=2*my;
61
62 597890 LOAD_COMMON
63 597890 int flags= c->sub_flags;
64
65 //FIXME factorize
66
67 597890 cmp_sub = s->mecc.me_sub_cmp[size];
68 597890 chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
69
70
2/2
✓ Branch 0 taken 707 times.
✓ Branch 1 taken 597183 times.
597890 if(c->skip){ //FIXME move out of hpel?
71 707 *mx_ptr = 0;
72 707 *my_ptr = 0;
73 707 return dmin;
74 }
75
76
2/2
✓ Branch 0 taken 186511 times.
✓ Branch 1 taken 410672 times.
597183 if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
77 186511 dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
78
6/6
✓ Branch 0 taken 39980 times.
✓ Branch 1 taken 146531 times.
✓ Branch 2 taken 23079 times.
✓ Branch 3 taken 16901 times.
✓ Branch 4 taken 963 times.
✓ Branch 5 taken 22116 times.
186511 if(mx || my || size>0)
79 164395 dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
80 }
81
82
6/6
✓ Branch 0 taken 592964 times.
✓ Branch 1 taken 4219 times.
✓ Branch 2 taken 589409 times.
✓ Branch 3 taken 3555 times.
✓ Branch 4 taken 586234 times.
✓ Branch 5 taken 3175 times.
597183 if (mx > xmin && mx < xmax &&
83
2/2
✓ Branch 0 taken 582910 times.
✓ Branch 1 taken 3324 times.
586234 my > ymin && my < ymax) {
84 582910 int d= dmin;
85 582910 const int index = my * (1 << ME_MAP_SHIFT) + mx;
86 582910 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
87 582910 + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor;
88 582910 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]
89 582910 + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
90 582910 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]
91 582910 + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
92 582910 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
93 582910 + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
94
95 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
96 unsigned key;
97 unsigned map_generation= c->map_generation;
98 key = (my - 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation;
99 av_assert2(c->map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
100 key = (my + 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation;
101 av_assert2(c->map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
102 key = (my) * (1 << ME_MAP_MV_BITS) + (mx + 1) + map_generation;
103 av_assert2(c->map[(index+1)&(ME_MAP_SIZE-1)] == key);
104 key = (my) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation;
105 av_assert2(c->map[(index-1)&(ME_MAP_SIZE-1)] == key);
106 #endif
107
2/2
✓ Branch 0 taken 289994 times.
✓ Branch 1 taken 292916 times.
582910 if(t<=b){
108 289994 CHECK_HALF_MV(0, 1, mx ,my-1)
109
2/2
✓ Branch 0 taken 173072 times.
✓ Branch 1 taken 116922 times.
289994 if(l<=r){
110 173072 CHECK_HALF_MV(1, 1, mx-1, my-1)
111
2/2
✓ Branch 0 taken 89741 times.
✓ Branch 1 taken 83331 times.
173072 if(t+r<=b+l){
112 89741 CHECK_HALF_MV(1, 1, mx , my-1)
113 }else{
114 83331 CHECK_HALF_MV(1, 1, mx-1, my )
115 }
116 173072 CHECK_HALF_MV(1, 0, mx-1, my )
117 }else{
118 116922 CHECK_HALF_MV(1, 1, mx , my-1)
119
2/2
✓ Branch 0 taken 59849 times.
✓ Branch 1 taken 57073 times.
116922 if(t+l<=b+r){
120 59849 CHECK_HALF_MV(1, 1, mx-1, my-1)
121 }else{
122 57073 CHECK_HALF_MV(1, 1, mx , my )
123 }
124 116922 CHECK_HALF_MV(1, 0, mx , my )
125 }
126 }else{
127
2/2
✓ Branch 0 taken 116527 times.
✓ Branch 1 taken 176389 times.
292916 if(l<=r){
128
2/2
✓ Branch 0 taken 53297 times.
✓ Branch 1 taken 63230 times.
116527 if(t+l<=b+r){
129 53297 CHECK_HALF_MV(1, 1, mx-1, my-1)
130 }else{
131 63230 CHECK_HALF_MV(1, 1, mx , my )
132 }
133 116527 CHECK_HALF_MV(1, 0, mx-1, my)
134 116527 CHECK_HALF_MV(1, 1, mx-1, my)
135 }else{
136
2/2
✓ Branch 0 taken 87441 times.
✓ Branch 1 taken 88948 times.
176389 if(t+r<=b+l){
137 87441 CHECK_HALF_MV(1, 1, mx , my-1)
138 }else{
139 88948 CHECK_HALF_MV(1, 1, mx-1, my)
140 }
141 176389 CHECK_HALF_MV(1, 0, mx , my)
142 176389 CHECK_HALF_MV(1, 1, mx , my)
143 }
144 292916 CHECK_HALF_MV(0, 1, mx , my)
145 }
146 av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
147 }
148
149 597183 *mx_ptr = bx;
150 597183 *my_ptr = by;
151
152 597183 return dmin;
153 }
154
155 106777 static int no_sub_motion_search(MpegEncContext * s,
156 int *mx_ptr, int *my_ptr, int dmin,
157 int src_index, int ref_index,
158 int size, int h)
159 {
160 106777 (*mx_ptr) *= 2;
161 106777 (*my_ptr) *= 2;
162 106777 return dmin;
163 }
164
165 697099 static inline int get_mb_score(MpegEncContext *s, int mx, int my,
166 int src_index, int ref_index, int size,
167 int h, int add_rate)
168 {
169 697099 MotionEstContext * const c= &s->me;
170 697099 const int penalty_factor= c->mb_penalty_factor;
171 697099 const int flags= c->mb_flags;
172 697099 const int qpel= flags & FLAG_QPEL;
173 697099 const int mask= 1+2*qpel;
174 me_cmp_func cmp_sub, chroma_cmp_sub;
175 int d;
176
177 697099 LOAD_COMMON
178
179 //FIXME factorize
180
181 697099 cmp_sub = s->mecc.mb_cmp[size];
182 697099 chroma_cmp_sub = s->mecc.mb_cmp[size + 1];
183
184 697099 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);
185 //FIXME check cbp before adding penalty for (0,0) vector
186
7/8
✓ Branch 0 taken 421159 times.
✓ Branch 1 taken 275940 times.
✓ Branch 2 taken 77377 times.
✓ Branch 3 taken 343782 times.
✓ Branch 4 taken 40509 times.
✓ Branch 5 taken 36868 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 40509 times.
697099 if(add_rate && (mx || my || size>0))
187 380650 d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor;
188
189 697099 return d;
190 }
191
192 275940 int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index,
193 int ref_index, int size, int h, int add_rate)
194 {
195 275940 return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
196 }
197
198 #define CHECK_QUARTER_MV(dx, dy, x, y)\
199 {\
200 const int hx= 4*(x)+(dx);\
201 const int hy= 4*(y)+(dy);\
202 d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
203 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
204 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
205 }
206
207 458724 static int qpel_motion_search(MpegEncContext * s,
208 int *mx_ptr, int *my_ptr, int dmin,
209 int src_index, int ref_index,
210 int size, int h)
211 {
212 458724 MotionEstContext * const c= &s->me;
213 458724 const int mx = *mx_ptr;
214 458724 const int my = *my_ptr;
215 458724 const int penalty_factor= c->sub_penalty_factor;
216 458724 const unsigned map_generation = c->map_generation;
217 458724 const int subpel_quality= c->avctx->me_subpel_quality;
218 458724 uint32_t *map= c->map;
219 me_cmp_func cmpf, chroma_cmpf;
220 me_cmp_func cmp_sub, chroma_cmp_sub;
221
222 458724 LOAD_COMMON
223 458724 int flags= c->sub_flags;
224
225 458724 cmpf = s->mecc.me_cmp[size];
226 458724 chroma_cmpf = s->mecc.me_cmp[size + 1]; // FIXME: factorize
227 //FIXME factorize
228
229 458724 cmp_sub = s->mecc.me_sub_cmp[size];
230 458724 chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
231
232
2/2
✓ Branch 0 taken 163 times.
✓ Branch 1 taken 458561 times.
458724 if(c->skip){ //FIXME somehow move up (benchmark)
233 163 *mx_ptr = 0;
234 163 *my_ptr = 0;
235 163 return dmin;
236 }
237
238
2/2
✓ Branch 0 taken 187104 times.
✓ Branch 1 taken 271457 times.
458561 if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
239 187104 dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
240
6/6
✓ Branch 0 taken 39985 times.
✓ Branch 1 taken 147119 times.
✓ Branch 2 taken 23595 times.
✓ Branch 3 taken 16390 times.
✓ Branch 4 taken 719 times.
✓ Branch 5 taken 22876 times.
187104 if(mx || my || size>0)
241 164228 dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor;
242 }
243
244
6/6
✓ Branch 0 taken 456531 times.
✓ Branch 1 taken 2030 times.
✓ Branch 2 taken 454844 times.
✓ Branch 3 taken 1687 times.
✓ Branch 4 taken 454617 times.
✓ Branch 5 taken 227 times.
458561 if (mx > xmin && mx < xmax &&
245
2/2
✓ Branch 0 taken 454190 times.
✓ Branch 1 taken 427 times.
454617 my > ymin && my < ymax) {
246 454190 int bx=4*mx, by=4*my;
247 454190 int d= dmin;
248 int i, nx, ny;
249 454190 const int index = my * (1 << ME_MAP_SHIFT) + mx;
250 454190 const int t= score_map[(index-(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)];
251 454190 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)];
252 454190 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)];
253 454190 const int b= score_map[(index+(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)];
254 454190 const int c= score_map[(index )&(ME_MAP_SIZE-1)];
255 int best[8];
256 int best_pos[8][2];
257
258 454190 memset(best, 64, sizeof(int)*8);
259
2/2
✓ Branch 0 taken 4320 times.
✓ Branch 1 taken 449870 times.
454190 if(s->me.dia_size>=2){
260 4320 const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
261 4320 const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
262 4320 const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
263 4320 const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
264
265
2/2
✓ Branch 0 taken 30240 times.
✓ Branch 1 taken 4320 times.
34560 for(ny= -3; ny <= 3; ny++){
266
2/2
✓ Branch 0 taken 211680 times.
✓ Branch 1 taken 30240 times.
241920 for(nx= -3; nx <= 3; nx++){
267 //FIXME this could overflow (unlikely though)
268 211680 const int64_t t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t;
269 211680 const int64_t c2= nx*nx*( r + l - 2*c) + 4*nx*( r- l) + 32*c;
270 211680 const int64_t b2= nx*nx*(br + bl - 2*b) + 4*nx*(br-bl) + 32*b;
271 211680 int score= (ny*ny*(b2 + t2 - 2*c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;
272 int i;
273
274
4/4
✓ Branch 0 taken 30240 times.
✓ Branch 1 taken 181440 times.
✓ Branch 2 taken 4320 times.
✓ Branch 3 taken 25920 times.
211680 if((nx&3)==0 && (ny&3)==0) continue;
275
276 207360 score += (mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
277
278 // if(nx&1) score-=1024*c->penalty_factor;
279 // if(ny&1) score-=1024*c->penalty_factor;
280
281
2/2
✓ Branch 0 taken 1073880 times.
✓ Branch 1 taken 93224 times.
1167104 for(i=0; i<8; i++){
282
2/2
✓ Branch 0 taken 114136 times.
✓ Branch 1 taken 959744 times.
1073880 if(score < best[i]){
283 114136 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
284 114136 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
285 114136 best[i]= score;
286 114136 best_pos[i][0]= nx + 4*mx;
287 114136 best_pos[i][1]= ny + 4*my;
288 114136 break;
289 }
290 }
291 }
292 }
293 }else{
294 int tl;
295 //FIXME this could overflow (unlikely though)
296 449870 const int cx = 4*(r - l);
297 449870 const int cx2= r + l - 2*c;
298 449870 const int cy = 4*(b - t);
299 449870 const int cy2= b + t - 2*c;
300 int cxy;
301
302 449870 if (map[(index - (1 << ME_MAP_SHIFT) - 1) & (ME_MAP_SIZE - 1)] ==
303
2/2
✓ Branch 0 taken 208378 times.
✓ Branch 1 taken 241492 times.
449870 (my - 1) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation) {
304 208378 tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
305 }else{
306 241492 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
307 }
308
309 449870 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*c;
310
311 av_assert2(16*cx2 + 4*cx + 32*c == 32*r);
312 av_assert2(16*cx2 - 4*cx + 32*c == 32*l);
313 av_assert2(16*cy2 + 4*cy + 32*c == 32*b);
314 av_assert2(16*cy2 - 4*cy + 32*c == 32*t);
315 av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
316
317
2/2
✓ Branch 0 taken 3149090 times.
✓ Branch 1 taken 449870 times.
3598960 for(ny= -3; ny <= 3; ny++){
318
2/2
✓ Branch 0 taken 22043630 times.
✓ Branch 1 taken 3149090 times.
25192720 for(nx= -3; nx <= 3; nx++){
319 //FIXME this could overflow (unlikely though)
320 22043630 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*c; //FIXME factor
321 int i;
322
323
4/4
✓ Branch 0 taken 3149090 times.
✓ Branch 1 taken 18894540 times.
✓ Branch 2 taken 449870 times.
✓ Branch 3 taken 2699220 times.
22043630 if((nx&3)==0 && (ny&3)==0) continue;
324
325 21593760 score += 32*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
326 // if(nx&1) score-=32*c->penalty_factor;
327 // if(ny&1) score-=32*c->penalty_factor;
328
329
2/2
✓ Branch 0 taken 117768271 times.
✓ Branch 1 taken 10152048 times.
127920319 for(i=0; i<8; i++){
330
2/2
✓ Branch 0 taken 11441712 times.
✓ Branch 1 taken 106326559 times.
117768271 if(score < best[i]){
331 11441712 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
332 11441712 memmove(best_pos[i + 1], best_pos[i], sizeof(best_pos[0]) * (7 - i));
333 11441712 best[i]= score;
334 11441712 best_pos[i][0]= nx + 4*mx;
335 11441712 best_pos[i][1]= ny + 4*my;
336 11441712 break;
337 }
338 }
339 }
340 }
341 }
342
2/2
✓ Branch 0 taken 3633520 times.
✓ Branch 1 taken 454190 times.
4087710 for(i=0; i<subpel_quality; i++){
343 3633520 nx= best_pos[i][0];
344 3633520 ny= best_pos[i][1];
345 3633520 CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2)
346 }
347
348 av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
349
350 454190 *mx_ptr = bx;
351 454190 *my_ptr = by;
352 }else{
353 4371 *mx_ptr =4*mx;
354 4371 *my_ptr =4*my;
355 }
356
357 458561 return dmin;
358 }
359
360
361 #define CHECK_MV(x,y)\
362 {\
363 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
364 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
365 av_assert2((x) >= xmin);\
366 av_assert2((x) <= xmax);\
367 av_assert2((y) >= ymin);\
368 av_assert2((y) <= ymax);\
369 if(map[index]!=key){\
370 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
371 map[index]= key;\
372 score_map[index]= d;\
373 d += (mv_penalty[((x)*(1<<shift))-pred_x] + mv_penalty[((y)*(1<<shift))-pred_y])*penalty_factor;\
374 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
375 }\
376 }
377
378 #define CHECK_CLIPPED_MV(ax,ay)\
379 {\
380 const int Lx= ax;\
381 const int Ly= ay;\
382 const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
383 const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
384 CHECK_MV(Lx2, Ly2)\
385 }
386
387 #define CHECK_MV_DIR(x,y,new_dir)\
388 {\
389 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
390 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
391 if(map[index]!=key){\
392 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
393 map[index]= key;\
394 score_map[index]= d;\
395 d += (mv_penalty[(int)((unsigned)(x)<<shift)-pred_x] + mv_penalty[(int)((unsigned)(y)<<shift)-pred_y])*penalty_factor;\
396 if(d<dmin){\
397 best[0]=x;\
398 best[1]=y;\
399 dmin=d;\
400 next_dir= new_dir;\
401 }\
402 }\
403 }
404
405 #define check(x,y,S,v)\
406 if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
407 if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
408 if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
409 if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
410
411 #define LOAD_COMMON2\
412 uint32_t *map= c->map;\
413 const int qpel= flags&FLAG_QPEL;\
414 const int shift= 1+qpel;\
415
416 5354026 static av_always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
417 int src_index, int ref_index, const int penalty_factor,
418 int size, int h, int flags)
419 {
420 5354026 MotionEstContext * const c= &s->me;
421 me_cmp_func cmpf, chroma_cmpf;
422 5354026 int next_dir=-1;
423 5354026 LOAD_COMMON
424 5354026 LOAD_COMMON2
425 5354026 unsigned map_generation = c->map_generation;
426
427 5354026 cmpf = s->mecc.me_cmp[size];
428 5354026 chroma_cmpf = s->mecc.me_cmp[size + 1];
429
430 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
431 5354026 const unsigned key = ((unsigned)best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation;
432 5354026 const int index= (((unsigned)best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1);
433
2/2
✓ Branch 0 taken 31905 times.
✓ Branch 1 taken 5322121 times.
5354026 if (map[index] != key) { // this will be executed only very rarely
434 31905 score_map[index]= cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
435 31905 map[index]= key;
436 }
437 }
438
439 1440178 for(;;){
440 int d;
441 6794204 const int dir= next_dir;
442 6794204 const int x= best[0];
443 6794204 const int y= best[1];
444 6794204 next_dir=-1;
445
446
8/8
✓ Branch 0 taken 6305974 times.
✓ Branch 1 taken 488230 times.
✓ Branch 2 taken 6196765 times.
✓ Branch 3 taken 109209 times.
✓ Branch 4 taken 3333218 times.
✓ Branch 5 taken 2863547 times.
✓ Branch 7 taken 469288 times.
✓ Branch 8 taken 2863930 times.
6794204 if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y , 0)
447
8/8
✓ Branch 0 taken 6475214 times.
✓ Branch 1 taken 318990 times.
✓ Branch 2 taken 6333993 times.
✓ Branch 3 taken 141221 times.
✓ Branch 4 taken 3715627 times.
✓ Branch 5 taken 2618366 times.
✓ Branch 7 taken 310162 times.
✓ Branch 8 taken 3405465 times.
6794204 if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1)
448
8/8
✓ Branch 0 taken 6429128 times.
✓ Branch 1 taken 365076 times.
✓ Branch 2 taken 6327739 times.
✓ Branch 3 taken 101389 times.
✓ Branch 4 taken 4065023 times.
✓ Branch 5 taken 2262716 times.
✓ Branch 7 taken 563942 times.
✓ Branch 8 taken 3501081 times.
6794204 if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y , 2)
449
8/8
✓ Branch 0 taken 6526322 times.
✓ Branch 1 taken 267882 times.
✓ Branch 2 taken 6402422 times.
✓ Branch 3 taken 123900 times.
✓ Branch 4 taken 4330339 times.
✓ Branch 5 taken 2072083 times.
✓ Branch 7 taken 318990 times.
✓ Branch 8 taken 4011349 times.
6794204 if(dir!=1 && y<ymax) CHECK_MV_DIR(x , y+1, 3)
450
451
2/2
✓ Branch 0 taken 5354026 times.
✓ Branch 1 taken 1440178 times.
6794204 if(next_dir==-1){
452 5354026 return dmin;
453 }
454 }
455 }
456
457 static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
458 int src_index, int ref_index, const int penalty_factor,
459 int size, int h, int flags)
460 {
461 MotionEstContext * const c= &s->me;
462 me_cmp_func cmpf, chroma_cmpf;
463 int dia_size;
464 LOAD_COMMON
465 LOAD_COMMON2
466 unsigned map_generation = c->map_generation;
467
468 cmpf = s->mecc.me_cmp[size];
469 chroma_cmpf = s->mecc.me_cmp[size + 1];
470
471 for(dia_size=1; dia_size<=4; dia_size++){
472 int dir;
473 const int x= best[0];
474 const int y= best[1];
475
476 if(dia_size&(dia_size-1)) continue;
477
478 if( x + dia_size > xmax
479 || x - dia_size < xmin
480 || y + dia_size > ymax
481 || y - dia_size < ymin)
482 continue;
483
484 for(dir= 0; dir<dia_size; dir+=2){
485 int d;
486
487 CHECK_MV(x + dir , y + dia_size - dir);
488 CHECK_MV(x + dia_size - dir, y - dir );
489 CHECK_MV(x - dir , y - dia_size + dir);
490 CHECK_MV(x - dia_size + dir, y + dir );
491 }
492
493 if(x!=best[0] || y!=best[1])
494 dia_size=0;
495 }
496 return dmin;
497 }
498
499 static int hex_search(MpegEncContext * s, int *best, int dmin,
500 int src_index, int ref_index, const int penalty_factor,
501 int size, int h, int flags, int dia_size)
502 {
503 MotionEstContext * const c= &s->me;
504 me_cmp_func cmpf, chroma_cmpf;
505 LOAD_COMMON
506 LOAD_COMMON2
507 unsigned map_generation = c->map_generation;
508 int x,y,d;
509 const int dec= dia_size & (dia_size-1);
510
511 cmpf = s->mecc.me_cmp[size];
512 chroma_cmpf = s->mecc.me_cmp[size + 1];
513
514 for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
515 do{
516 x= best[0];
517 y= best[1];
518
519 CHECK_CLIPPED_MV(x -dia_size , y);
520 CHECK_CLIPPED_MV(x+ dia_size , y);
521 CHECK_CLIPPED_MV(x+( dia_size>>1), y+dia_size);
522 CHECK_CLIPPED_MV(x+( dia_size>>1), y-dia_size);
523 if(dia_size>1){
524 CHECK_CLIPPED_MV(x+(-dia_size>>1), y+dia_size);
525 CHECK_CLIPPED_MV(x+(-dia_size>>1), y-dia_size);
526 }
527 }while(best[0] != x || best[1] != y);
528 }
529
530 return dmin;
531 }
532
533 static int l2s_dia_search(MpegEncContext * s, int *best, int dmin,
534 int src_index, int ref_index, const int penalty_factor,
535 int size, int h, int flags)
536 {
537 MotionEstContext * const c= &s->me;
538 me_cmp_func cmpf, chroma_cmpf;
539 LOAD_COMMON
540 LOAD_COMMON2
541 unsigned map_generation = c->map_generation;
542 int x,y,i,d;
543 int dia_size= c->dia_size&0xFF;
544 const int dec= dia_size & (dia_size-1);
545 static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
546 { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
547
548 cmpf = s->mecc.me_cmp[size];
549 chroma_cmpf = s->mecc.me_cmp[size + 1];
550
551 for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
552 do{
553 x= best[0];
554 y= best[1];
555 for(i=0; i<8; i++){
556 CHECK_CLIPPED_MV(x+hex[i][0]*dia_size, y+hex[i][1]*dia_size);
557 }
558 }while(best[0] != x || best[1] != y);
559 }
560
561 x= best[0];
562 y= best[1];
563 CHECK_CLIPPED_MV(x+1, y);
564 CHECK_CLIPPED_MV(x, y+1);
565 CHECK_CLIPPED_MV(x-1, y);
566 CHECK_CLIPPED_MV(x, y-1);
567
568 return dmin;
569 }
570
571 static int umh_search(MpegEncContext * s, int *best, int dmin,
572 int src_index, int ref_index, const int penalty_factor,
573 int size, int h, int flags)
574 {
575 MotionEstContext * const c= &s->me;
576 me_cmp_func cmpf, chroma_cmpf;
577 LOAD_COMMON
578 LOAD_COMMON2
579 unsigned map_generation = c->map_generation;
580 int x,y,x2,y2, i, j, d;
581 const int dia_size= c->dia_size&0xFE;
582 static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
583 { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
584 {-2, 3}, { 0, 4}, { 2, 3},
585 {-2,-3}, { 0,-4}, { 2,-3},};
586
587 cmpf = s->mecc.me_cmp[size];
588 chroma_cmpf = s->mecc.me_cmp[size + 1];
589
590 x= best[0];
591 y= best[1];
592 for(x2=FFMAX(x-dia_size+1, xmin); x2<=FFMIN(x+dia_size-1,xmax); x2+=2){
593 CHECK_MV(x2, y);
594 }
595 for(y2=FFMAX(y-dia_size/2+1, ymin); y2<=FFMIN(y+dia_size/2-1,ymax); y2+=2){
596 CHECK_MV(x, y2);
597 }
598
599 x= best[0];
600 y= best[1];
601 for(y2=FFMAX(y-2, ymin); y2<=FFMIN(y+2,ymax); y2++){
602 for(x2=FFMAX(x-2, xmin); x2<=FFMIN(x+2,xmax); x2++){
603 CHECK_MV(x2, y2);
604 }
605 }
606
607 //FIXME prevent the CLIP stuff
608
609 for(j=1; j<=dia_size/4; j++){
610 for(i=0; i<16; i++){
611 CHECK_CLIPPED_MV(x+hex[i][0]*j, y+hex[i][1]*j);
612 }
613 }
614
615 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
616 }
617
618 static int full_search(MpegEncContext * s, int *best, int dmin,
619 int src_index, int ref_index, const int penalty_factor,
620 int size, int h, int flags)
621 {
622 MotionEstContext * const c= &s->me;
623 me_cmp_func cmpf, chroma_cmpf;
624 LOAD_COMMON
625 LOAD_COMMON2
626 unsigned map_generation = c->map_generation;
627 int x,y, d;
628 const int dia_size= c->dia_size&0xFF;
629
630 cmpf = s->mecc.me_cmp[size];
631 chroma_cmpf = s->mecc.me_cmp[size + 1];
632
633 for(y=FFMAX(-dia_size, ymin); y<=FFMIN(dia_size,ymax); y++){
634 for(x=FFMAX(-dia_size, xmin); x<=FFMIN(dia_size,xmax); x++){
635 CHECK_MV(x, y);
636 }
637 }
638
639 x= best[0];
640 y= best[1];
641 d= dmin;
642 CHECK_CLIPPED_MV(x , y);
643 CHECK_CLIPPED_MV(x+1, y);
644 CHECK_CLIPPED_MV(x, y+1);
645 CHECK_CLIPPED_MV(x-1, y);
646 CHECK_CLIPPED_MV(x, y-1);
647 best[0]= x;
648 best[1]= y;
649
650 return d;
651 }
652
653 #define SAB_CHECK_MV(ax,ay)\
654 {\
655 const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
656 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
657 if(map[index]!=key){\
658 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
659 map[index]= key;\
660 score_map[index]= d;\
661 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
662 if(d < minima[minima_count-1].height){\
663 int j=0;\
664 \
665 while(d >= minima[j].height) j++;\
666 \
667 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
668 \
669 minima[j].checked= 0;\
670 minima[j].height= d;\
671 minima[j].x= ax;\
672 minima[j].y= ay;\
673 \
674 i=-1;\
675 continue;\
676 }\
677 }\
678 }
679
680 #define MAX_SAB_SIZE ME_MAP_SIZE
681 static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
682 int src_index, int ref_index, const int penalty_factor,
683 int size, int h, int flags)
684 {
685 MotionEstContext * const c= &s->me;
686 me_cmp_func cmpf, chroma_cmpf;
687 Minima minima[MAX_SAB_SIZE];
688 const int minima_count= FFABS(c->dia_size);
689 int i, j;
690 LOAD_COMMON
691 LOAD_COMMON2
692 unsigned map_generation = c->map_generation;
693
694 av_assert1(minima_count <= MAX_SAB_SIZE);
695
696 cmpf = s->mecc.me_cmp[size];
697 chroma_cmpf = s->mecc.me_cmp[size + 1];
698
699 /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
700 become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
701 */
702 for(j=i=0; i<ME_MAP_SIZE && j<MAX_SAB_SIZE; i++){
703 uint32_t key= map[i];
704
705 key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));
706
707 if ((key & (-(1 << (2 * ME_MAP_MV_BITS)))) != map_generation)
708 continue;
709
710 minima[j].height= score_map[i];
711 minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;
712 minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1);
713 minima[j].x-= (1<<(ME_MAP_MV_BITS-1));
714 minima[j].y-= (1<<(ME_MAP_MV_BITS-1));
715
716 // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
717 if( minima[j].x > xmax || minima[j].x < xmin
718 || minima[j].y > ymax || minima[j].y < ymin)
719 continue;
720
721 minima[j].checked=0;
722 if(minima[j].x || minima[j].y)
723 minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor;
724
725 j++;
726 }
727
728 AV_QSORT(minima, j, Minima, minima_cmp);
729
730 for(; j<minima_count; j++){
731 minima[j].height=256*256*256*64;
732 minima[j].checked=0;
733 minima[j].x= minima[j].y=0;
734 }
735
736 for(i=0; i<minima_count; i++){
737 const int x= minima[i].x;
738 const int y= minima[i].y;
739 int d;
740
741 if(minima[i].checked) continue;
742
743 if( x >= xmax || x <= xmin
744 || y >= ymax || y <= ymin)
745 continue;
746
747 SAB_CHECK_MV(x-1, y)
748 SAB_CHECK_MV(x+1, y)
749 SAB_CHECK_MV(x , y-1)
750 SAB_CHECK_MV(x , y+1)
751
752 minima[i].checked= 1;
753 }
754
755 best[0]= minima[0].x;
756 best[1]= minima[0].y;
757 dmin= minima[0].height;
758
759 if( best[0] < xmax && best[0] > xmin
760 && best[1] < ymax && best[1] > ymin){
761 int d;
762 // ensure that the reference samples for hpel refinement are in the map
763 CHECK_MV(best[0]-1, best[1])
764 CHECK_MV(best[0]+1, best[1])
765 CHECK_MV(best[0], best[1]-1)
766 CHECK_MV(best[0], best[1]+1)
767 }
768 return dmin;
769 }
770
771 8640 static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
772 int src_index, int ref_index, const int penalty_factor,
773 int size, int h, int flags)
774 {
775 8640 MotionEstContext * const c= &s->me;
776 me_cmp_func cmpf, chroma_cmpf;
777 int dia_size;
778 8640 LOAD_COMMON
779 8640 LOAD_COMMON2
780 8640 unsigned map_generation = c->map_generation;
781
782 8640 cmpf = s->mecc.me_cmp[size];
783 8640 chroma_cmpf = s->mecc.me_cmp[size + 1];
784
785
2/2
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 8640 times.
26708 for(dia_size=1; dia_size<=c->dia_size; dia_size++){
786 int dir, start, end;
787 18068 const int x= best[0];
788 18068 const int y= best[1];
789
790 18068 start= FFMAX(0, y + dia_size - ymax);
791 18068 end = FFMIN(dia_size, xmax - x + 1);
792
2/2
✓ Branch 0 taken 26941 times.
✓ Branch 1 taken 18068 times.
45009 for(dir= start; dir<end; dir++){
793 int d;
794
795 //check(x + dir,y + dia_size - dir,0, a0)
796
2/2
✓ Branch 0 taken 21405 times.
✓ Branch 1 taken 5536 times.
26941 CHECK_MV(x + dir , y + dia_size - dir);
797 }
798
799 18068 start= FFMAX(0, x + dia_size - xmax);
800 18068 end = FFMIN(dia_size, y - ymin + 1);
801
2/2
✓ Branch 0 taken 26941 times.
✓ Branch 1 taken 18068 times.
45009 for(dir= start; dir<end; dir++){
802 int d;
803
804 //check(x + dia_size - dir, y - dir,0, a1)
805
2/2
✓ Branch 0 taken 20048 times.
✓ Branch 1 taken 6893 times.
26941 CHECK_MV(x + dia_size - dir, y - dir );
806 }
807
808 18068 start= FFMAX(0, -y + dia_size + ymin );
809 18068 end = FFMIN(dia_size, x - xmin + 1);
810
2/2
✓ Branch 0 taken 26941 times.
✓ Branch 1 taken 18068 times.
45009 for(dir= start; dir<end; dir++){
811 int d;
812
813 //check(x - dir,y - dia_size + dir,0, a2)
814
2/2
✓ Branch 0 taken 14357 times.
✓ Branch 1 taken 12584 times.
26941 CHECK_MV(x - dir , y - dia_size + dir);
815 }
816
817 18068 start= FFMAX(0, -x + dia_size + xmin );
818 18068 end = FFMIN(dia_size, ymax - y + 1);
819
2/2
✓ Branch 0 taken 26941 times.
✓ Branch 1 taken 18068 times.
45009 for(dir= start; dir<end; dir++){
820 int d;
821
822 //check(x - dia_size + dir, y + dir,0, a3)
823
2/2
✓ Branch 0 taken 12766 times.
✓ Branch 1 taken 14175 times.
26941 CHECK_MV(x - dia_size + dir, y + dir );
824 }
825
826
4/4
✓ Branch 0 taken 17607 times.
✓ Branch 1 taken 461 times.
✓ Branch 2 taken 94 times.
✓ Branch 3 taken 17513 times.
18068 if(x!=best[0] || y!=best[1])
827 555 dia_size=0;
828 }
829 8640 return dmin;
830 }
831
832 5362666 static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dmin,
833 int src_index, int ref_index, const int penalty_factor,
834 int size, int h, int flags){
835 5362666 MotionEstContext * const c= &s->me;
836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5362666 times.
5362666 if(c->dia_size==-1)
837 return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5362666 times.
5362666 else if(c->dia_size<-1)
839 return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
840
2/2
✓ Branch 0 taken 5354026 times.
✓ Branch 1 taken 8640 times.
5362666 else if(c->dia_size<2)
841 5354026 return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8640 times.
8640 else if(c->dia_size>1024)
843 return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8640 times.
8640 else if(c->dia_size>768)
845 return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8640 times.
8640 else if(c->dia_size>512)
847 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->dia_size&0xFF);
848
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8640 times.
8640 else if(c->dia_size>256)
849 return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
850 else
851 8640 return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
852 }
853
854 /**
855 @param P a list of candidate mvs to check before starting the
856 iterative search. If one of the candidates is close to the optimal mv, then
857 it takes fewer iterations. And it increases the chance that we find the
858 optimal mv.
859 */
860 3127645 static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx_ptr, int *my_ptr,
861 int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
862 int ref_mv_scale, int flags, int size, int h)
863 {
864 3127645 MotionEstContext * const c= &s->me;
865 3127645 int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
866 i.e. the difference between the position of the
867 block currently being encoded and the position of
868 the block chosen to predict it from. */
869 int d; ///< the score (cmp + penalty) of any given mv
870 int dmin; /**< the best value of d, i.e. the score
871 corresponding to the mv stored in best[]. */
872 unsigned map_generation;
873 int penalty_factor;
874 3127645 const int ref_mv_stride= s->mb_stride; //pass as arg FIXME
875 3127645 const int ref_mv_xy = s->mb_x + s->mb_y * ref_mv_stride; // add to last_mv before passing FIXME
876 me_cmp_func cmpf, chroma_cmpf;
877
878 3127645 LOAD_COMMON
879 3127645 LOAD_COMMON2
880
881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3127645 times.
3127645 if(c->pre_pass){
882 penalty_factor= c->pre_penalty_factor;
883 cmpf = s->mecc.me_pre_cmp[size];
884 chroma_cmpf = s->mecc.me_pre_cmp[size + 1];
885 }else{
886 3127645 penalty_factor= c->penalty_factor;
887 3127645 cmpf = s->mecc.me_cmp[size];
888 3127645 chroma_cmpf = s->mecc.me_cmp[size + 1];
889 }
890
891 3127645 map_generation= update_map_generation(c);
892
893 av_assert2(cmpf);
894 3127645 dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
895 3127645 map[0]= map_generation;
896 3127645 score_map[0]= dmin;
897
898 //FIXME precalc first term below?
899
4/4
✓ Branch 0 taken 1007803 times.
✓ Branch 1 taken 2119842 times.
✓ Branch 2 taken 191415 times.
✓ Branch 3 taken 816388 times.
3127645 if ((s->pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) ||
900
2/2
✓ Branch 0 taken 138868 times.
✓ Branch 1 taken 2172389 times.
2311257 s->mpv_flags & FF_MPV_FLAG_MV0)
901 955256 dmin += (mv_penalty[pred_x] + mv_penalty[pred_y])*penalty_factor;
902
903 /* first line */
904
2/2
✓ Branch 0 taken 177310 times.
✓ Branch 1 taken 2950335 times.
3127645 if (s->first_slice_line) {
905
2/2
✓ Branch 0 taken 148825 times.
✓ Branch 1 taken 28485 times.
177310 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
906
2/2
✓ Branch 0 taken 93969 times.
✓ Branch 1 taken 83341 times.
177310 CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
907 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
908 }else{
909
2/2
✓ Branch 0 taken 114105 times.
✓ Branch 1 taken 2836230 times.
2950335 if(dmin<((h*h*s->avctx->mv0_threshold)>>8)
910 114105 && ( P_LEFT[0] |P_LEFT[1]
911 114105 |P_TOP[0] |P_TOP[1]
912
2/2
✓ Branch 0 taken 97235 times.
✓ Branch 1 taken 16870 times.
114105 |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){
913 97235 *mx_ptr= 0;
914 97235 *my_ptr= 0;
915 97235 c->skip=1;
916 97235 return dmin;
917 }
918
2/2
✓ Branch 0 taken 2620134 times.
✓ Branch 1 taken 232966 times.
2853100 CHECK_MV( P_MEDIAN[0] >>shift , P_MEDIAN[1] >>shift)
919
2/2
✓ Branch 0 taken 2806258 times.
✓ Branch 1 taken 46842 times.
2853100 CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)-1)
920
2/2
✓ Branch 0 taken 2742226 times.
✓ Branch 1 taken 110874 times.
2853100 CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)+1)
921
2/2
✓ Branch 0 taken 2745853 times.
✓ Branch 1 taken 107247 times.
2853100 CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)-1, (P_MEDIAN[1]>>shift) )
922
2/2
✓ Branch 0 taken 2729085 times.
✓ Branch 1 taken 124015 times.
2853100 CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)+1, (P_MEDIAN[1]>>shift) )
923
2/2
✓ Branch 0 taken 916744 times.
✓ Branch 1 taken 1936356 times.
2853100 CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
924 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
925
2/2
✓ Branch 0 taken 574550 times.
✓ Branch 1 taken 2278550 times.
2853100 CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift)
926
2/2
✓ Branch 0 taken 265114 times.
✓ Branch 1 taken 2587986 times.
2853100 CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift)
927
2/2
✓ Branch 0 taken 400172 times.
✓ Branch 1 taken 2452928 times.
2853100 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)
928 }
929
2/2
✓ Branch 0 taken 2266559 times.
✓ Branch 1 taken 763851 times.
3030410 if(dmin>h*h*4){
930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2266559 times.
2266559 if(c->pre_pass){
931 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16,
932 (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
933 if(!s->first_slice_line)
934 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
935 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
936 }else{
937
2/2
✓ Branch 0 taken 477009 times.
✓ Branch 1 taken 1789550 times.
2266559 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
938 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
939
2/2
✓ Branch 0 taken 2002204 times.
✓ Branch 1 taken 264355 times.
2266559 if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line
940
2/2
✓ Branch 0 taken 516433 times.
✓ Branch 1 taken 1485771 times.
2002204 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
941 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
942 }
943 }
944
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030410 times.
3030410 if(c->avctx->last_predictor_count){
946 const int count= c->avctx->last_predictor_count;
947 const int xstart= FFMAX(0, s->mb_x - count);
948 const int ystart= FFMAX(0, s->mb_y - count);
949 const int xend= FFMIN(s->mb_width , s->mb_x + count + 1);
950 const int yend= FFMIN(s->mb_height, s->mb_y + count + 1);
951 int mb_y;
952
953 for(mb_y=ystart; mb_y<yend; mb_y++){
954 int mb_x;
955 for(mb_x=xstart; mb_x<xend; mb_x++){
956 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
957 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
958 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
959
960 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;
961 CHECK_MV(mx,my)
962 }
963 }
964 }
965
966 //check(best[0],best[1],0, b0)
967 3030410 dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
968
969 //check(best[0],best[1],0, b1)
970 3030410 *mx_ptr= best[0];
971 3030410 *my_ptr= best[1];
972
973 3030410 return dmin;
974 }
975
976 //this function is dedicated to the brain damaged gcc
977 3127645 int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr,
978 int P[10][2], int src_index, int ref_index,
979 int16_t (*last_mv)[2], int ref_mv_scale,
980 int size, int h)
981 {
982 3127645 MotionEstContext * const c= &s->me;
983 //FIXME convert other functions in the same way if faster
984
4/6
✓ Branch 0 taken 2572432 times.
✓ Branch 1 taken 555213 times.
✓ Branch 2 taken 2572432 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2572432 times.
✗ Branch 5 not taken.
3127645 if(c->flags==0 && h==16 && size==0){
985 2572432 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
986 // case FLAG_QPEL:
987 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
988 }else{
989 555213 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->flags, size, h);
990 }
991 }
992
993 2332256 static int epzs_motion_search2(MpegEncContext * s,
994 int *mx_ptr, int *my_ptr, int P[10][2],
995 int src_index, int ref_index, int16_t (*last_mv)[2],
996 int ref_mv_scale, const int size)
997 {
998 2332256 MotionEstContext * const c= &s->me;
999 2332256 int best[2]={0, 0};
1000 int d, dmin;
1001 unsigned map_generation;
1002 2332256 const int penalty_factor= c->penalty_factor;
1003 2332256 const int h=8;
1004 2332256 const int ref_mv_stride= s->mb_stride;
1005 2332256 const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
1006 me_cmp_func cmpf, chroma_cmpf;
1007 2332256 LOAD_COMMON
1008 2332256 int flags= c->flags;
1009 2332256 LOAD_COMMON2
1010
1011 2332256 cmpf = s->mecc.me_cmp[size];
1012 2332256 chroma_cmpf = s->mecc.me_cmp[size + 1];
1013
1014 2332256 map_generation= update_map_generation(c);
1015
1016 2332256 dmin = 1000000;
1017
1018 /* first line */
1019
2/2
✓ Branch 0 taken 181096 times.
✓ Branch 1 taken 2151160 times.
2332256 if (s->first_slice_line) {
1020
1/2
✓ Branch 0 taken 181096 times.
✗ Branch 1 not taken.
181096 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
1021
2/2
✓ Branch 0 taken 154821 times.
✓ Branch 1 taken 26275 times.
181096 CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
1022 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1023
2/2
✓ Branch 0 taken 108461 times.
✓ Branch 1 taken 72635 times.
181096 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
1024 }else{
1025
1/2
✓ Branch 0 taken 2151160 times.
✗ Branch 1 not taken.
2151160 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
1026 //FIXME try some early stop
1027
2/2
✓ Branch 0 taken 1284079 times.
✓ Branch 1 taken 867081 times.
2151160 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)
1028
2/2
✓ Branch 0 taken 834027 times.
✓ Branch 1 taken 1317133 times.
2151160 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
1029
2/2
✓ Branch 0 taken 515874 times.
✓ Branch 1 taken 1635286 times.
2151160 CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift)
1030
2/2
✓ Branch 0 taken 722707 times.
✓ Branch 1 taken 1428453 times.
2151160 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)
1031
2/2
✓ Branch 0 taken 1522512 times.
✓ Branch 1 taken 628648 times.
2151160 CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
1032 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1033 }
1034
2/2
✓ Branch 0 taken 2036249 times.
✓ Branch 1 taken 296007 times.
2332256 if(dmin>64*4){
1035
2/2
✓ Branch 0 taken 797959 times.
✓ Branch 1 taken 1238290 times.
2036249 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
1036 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1037
2/2
✓ Branch 0 taken 1872966 times.
✓ Branch 1 taken 163283 times.
2036249 if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line
1038
2/2
✓ Branch 0 taken 763641 times.
✓ Branch 1 taken 1109325 times.
1872966 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1039 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1040 }
1041
1042 2332256 dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1043
1044 2332256 *mx_ptr= best[0];
1045 2332256 *my_ptr= best[1];
1046
1047 2332256 return dmin;
1048 }
1049