| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com> | ||
| 3 | * | ||
| 4 | * This file is part of FFmpeg. | ||
| 5 | * | ||
| 6 | * FFmpeg is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU Lesser General Public | ||
| 8 | * License as published by the Free Software Foundation; either | ||
| 9 | * version 2.1 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * Lesser General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU Lesser General Public | ||
| 17 | * License along with FFmpeg; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include "libavutil/common.h" | ||
| 22 | #include "motion_estimation.h" | ||
| 23 | |||
| 24 | static const int8_t sqr1[8][2] = {{ 0,-1}, { 0, 1}, {-1, 0}, { 1, 0}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}}; | ||
| 25 | static const int8_t dia1[4][2] = {{-1, 0}, { 0,-1}, { 1, 0}, { 0, 1}}; | ||
| 26 | static const int8_t dia2[8][2] = {{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1}, { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}}; | ||
| 27 | static const int8_t hex2[6][2] = {{-2, 0}, {-1,-2}, {-1, 2}, { 1,-2}, { 1, 2}, { 2, 0}}; | ||
| 28 | static const int8_t hex4[16][2] = {{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2}, | ||
| 29 | { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2}, | ||
| 30 | {-2, 3}, { 0, 4}, { 2, 3}, {-2,-3}, { 0,-4}, { 2,-3}}; | ||
| 31 | |||
| 32 | #define COST_MV(x, y)\ | ||
| 33 | do {\ | ||
| 34 | cost = me_ctx->get_cost(me_ctx, x_mb, y_mb, x, y);\ | ||
| 35 | if (cost < cost_min) {\ | ||
| 36 | cost_min = cost;\ | ||
| 37 | mv[0] = x;\ | ||
| 38 | mv[1] = y;\ | ||
| 39 | }\ | ||
| 40 | } while(0) | ||
| 41 | |||
| 42 | #define COST_P_MV(x, y)\ | ||
| 43 | if (x >= x_min && x <= x_max && y >= y_min && y <= y_max)\ | ||
| 44 | COST_MV(x, y); | ||
| 45 | |||
| 46 | 4 | void ff_me_init_context(AVMotionEstContext *me_ctx, int mb_size, int search_param, | |
| 47 | int width, int height, int x_min, int x_max, int y_min, int y_max) | ||
| 48 | { | ||
| 49 | 4 | me_ctx->width = width; | |
| 50 | 4 | me_ctx->height = height; | |
| 51 | 4 | me_ctx->mb_size = mb_size; | |
| 52 | 4 | me_ctx->search_param = search_param; | |
| 53 | 4 | me_ctx->get_cost = &ff_me_cmp_sad; | |
| 54 | 4 | me_ctx->x_min = x_min; | |
| 55 | 4 | me_ctx->x_max = x_max; | |
| 56 | 4 | me_ctx->y_min = y_min; | |
| 57 | 4 | me_ctx->y_max = y_max; | |
| 58 | 4 | } | |
| 59 | |||
| 60 | 6552105 | uint64_t ff_me_cmp_sad(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int x_mv, int y_mv) | |
| 61 | { | ||
| 62 | 6552105 | const int linesize = me_ctx->linesize; | |
| 63 | 6552105 | uint8_t *data_ref = me_ctx->data_ref; | |
| 64 | 6552105 | uint8_t *data_cur = me_ctx->data_cur; | |
| 65 | 6552105 | uint64_t sad = 0; | |
| 66 | int i, j; | ||
| 67 | |||
| 68 | 6552105 | data_ref += y_mv * linesize; | |
| 69 | 6552105 | data_cur += y_mb * linesize; | |
| 70 | |||
| 71 |
2/2✓ Branch 0 taken 104833680 times.
✓ Branch 1 taken 6552105 times.
|
111385785 | for (j = 0; j < me_ctx->mb_size; j++) |
| 72 |
2/2✓ Branch 0 taken 1677338880 times.
✓ Branch 1 taken 104833680 times.
|
1782172560 | for (i = 0; i < me_ctx->mb_size; i++) |
| 73 |
2/2✓ Branch 0 taken 992363353 times.
✓ Branch 1 taken 684975527 times.
|
1677338880 | sad += FFABS(data_ref[x_mv + i + j * linesize] - data_cur[x_mb + i + j * linesize]); |
| 74 | |||
| 75 | 6552105 | return sad; | |
| 76 | } | ||
| 77 | |||
| 78 | 229680 | uint64_t ff_me_search_esa(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 79 | { | ||
| 80 | int x, y; | ||
| 81 | 229680 | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 82 | 229680 | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 83 | 229680 | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 84 | 229680 | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 85 | uint64_t cost, cost_min; | ||
| 86 | |||
| 87 |
2/2✓ Branch 1 taken 201480 times.
✓ Branch 2 taken 28200 times.
|
229680 | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) |
| 88 | 201480 | return cost_min; | |
| 89 | |||
| 90 |
2/2✓ Branch 0 taken 422944 times.
✓ Branch 1 taken 28200 times.
|
451144 | for (y = y_min; y <= y_max; y++) |
| 91 |
2/2✓ Branch 0 taken 6322425 times.
✓ Branch 1 taken 422944 times.
|
6745369 | for (x = x_min; x <= x_max; x++) |
| 92 |
2/2✓ Branch 1 taken 135811 times.
✓ Branch 2 taken 6186614 times.
|
6322425 | COST_MV(x, y); |
| 93 | |||
| 94 | 28200 | return cost_min; | |
| 95 | } | ||
| 96 | |||
| 97 | ✗ | uint64_t ff_me_search_tss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 98 | { | ||
| 99 | int x, y; | ||
| 100 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 101 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 102 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 103 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 104 | uint64_t cost, cost_min; | ||
| 105 | ✗ | int step = ROUNDED_DIV(me_ctx->search_param, 2); | |
| 106 | int i; | ||
| 107 | |||
| 108 | ✗ | mv[0] = x_mb; | |
| 109 | ✗ | mv[1] = y_mb; | |
| 110 | |||
| 111 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 112 | ✗ | return cost_min; | |
| 113 | |||
| 114 | do { | ||
| 115 | ✗ | x = mv[0]; | |
| 116 | ✗ | y = mv[1]; | |
| 117 | |||
| 118 | ✗ | for (i = 0; i < 8; i++) | |
| 119 | ✗ | COST_P_MV(x + sqr1[i][0] * step, y + sqr1[i][1] * step); | |
| 120 | |||
| 121 | ✗ | step = step >> 1; | |
| 122 | |||
| 123 | ✗ | } while (step > 0); | |
| 124 | |||
| 125 | ✗ | return cost_min; | |
| 126 | } | ||
| 127 | |||
| 128 | ✗ | uint64_t ff_me_search_tdls(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 129 | { | ||
| 130 | int x, y; | ||
| 131 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 132 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 133 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 134 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 135 | uint64_t cost, cost_min; | ||
| 136 | ✗ | int step = ROUNDED_DIV(me_ctx->search_param, 2); | |
| 137 | int i; | ||
| 138 | |||
| 139 | ✗ | mv[0] = x_mb; | |
| 140 | ✗ | mv[1] = y_mb; | |
| 141 | |||
| 142 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 143 | ✗ | return cost_min; | |
| 144 | |||
| 145 | do { | ||
| 146 | ✗ | x = mv[0]; | |
| 147 | ✗ | y = mv[1]; | |
| 148 | |||
| 149 | ✗ | for (i = 0; i < 4; i++) | |
| 150 | ✗ | COST_P_MV(x + dia1[i][0] * step, y + dia1[i][1] * step); | |
| 151 | |||
| 152 | ✗ | if (x == mv[0] && y == mv[1]) | |
| 153 | ✗ | step = step >> 1; | |
| 154 | |||
| 155 | ✗ | } while (step > 0); | |
| 156 | |||
| 157 | ✗ | return cost_min; | |
| 158 | } | ||
| 159 | |||
| 160 | ✗ | uint64_t ff_me_search_ntss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 161 | { | ||
| 162 | int x, y; | ||
| 163 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 164 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 165 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 166 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 167 | uint64_t cost, cost_min; | ||
| 168 | ✗ | int step = ROUNDED_DIV(me_ctx->search_param, 2); | |
| 169 | ✗ | int first_step = 1; | |
| 170 | int i; | ||
| 171 | |||
| 172 | ✗ | mv[0] = x_mb; | |
| 173 | ✗ | mv[1] = y_mb; | |
| 174 | |||
| 175 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 176 | ✗ | return cost_min; | |
| 177 | |||
| 178 | do { | ||
| 179 | ✗ | x = mv[0]; | |
| 180 | ✗ | y = mv[1]; | |
| 181 | |||
| 182 | ✗ | for (i = 0; i < 8; i++) | |
| 183 | ✗ | COST_P_MV(x + sqr1[i][0] * step, y + sqr1[i][1] * step); | |
| 184 | |||
| 185 | /* addition to TSS in NTSS */ | ||
| 186 | ✗ | if (first_step) { | |
| 187 | |||
| 188 | ✗ | for (i = 0; i < 8; i++) | |
| 189 | ✗ | COST_P_MV(x + sqr1[i][0], y + sqr1[i][1]); | |
| 190 | |||
| 191 | ✗ | if (x == mv[0] && y == mv[1]) | |
| 192 | ✗ | return cost_min; | |
| 193 | |||
| 194 | ✗ | if (FFABS(x - mv[0]) <= 1 && FFABS(y - mv[1]) <= 1) { | |
| 195 | ✗ | x = mv[0]; | |
| 196 | ✗ | y = mv[1]; | |
| 197 | |||
| 198 | ✗ | for (i = 0; i < 8; i++) | |
| 199 | ✗ | COST_P_MV(x + sqr1[i][0], y + sqr1[i][1]); | |
| 200 | ✗ | return cost_min; | |
| 201 | } | ||
| 202 | |||
| 203 | ✗ | first_step = 0; | |
| 204 | } | ||
| 205 | |||
| 206 | ✗ | step = step >> 1; | |
| 207 | |||
| 208 | ✗ | } while (step > 0); | |
| 209 | |||
| 210 | ✗ | return cost_min; | |
| 211 | } | ||
| 212 | |||
| 213 | ✗ | uint64_t ff_me_search_fss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 214 | { | ||
| 215 | int x, y; | ||
| 216 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 217 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 218 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 219 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 220 | uint64_t cost, cost_min; | ||
| 221 | ✗ | int step = 2; | |
| 222 | int i; | ||
| 223 | |||
| 224 | ✗ | mv[0] = x_mb; | |
| 225 | ✗ | mv[1] = y_mb; | |
| 226 | |||
| 227 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 228 | ✗ | return cost_min; | |
| 229 | |||
| 230 | do { | ||
| 231 | ✗ | x = mv[0]; | |
| 232 | ✗ | y = mv[1]; | |
| 233 | |||
| 234 | ✗ | for (i = 0; i < 8; i++) | |
| 235 | ✗ | COST_P_MV(x + sqr1[i][0] * step, y + sqr1[i][1] * step); | |
| 236 | |||
| 237 | ✗ | if (x == mv[0] && y == mv[1]) | |
| 238 | ✗ | step = step >> 1; | |
| 239 | |||
| 240 | ✗ | } while (step > 0); | |
| 241 | |||
| 242 | ✗ | return cost_min; | |
| 243 | } | ||
| 244 | |||
| 245 | ✗ | uint64_t ff_me_search_ds(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 246 | { | ||
| 247 | int x, y; | ||
| 248 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 249 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 250 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 251 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 252 | uint64_t cost, cost_min; | ||
| 253 | int i; | ||
| 254 | av_unused int dir_x, dir_y; | ||
| 255 | |||
| 256 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 257 | ✗ | return cost_min; | |
| 258 | |||
| 259 | ✗ | x = x_mb; y = y_mb; | |
| 260 | ✗ | dir_x = dir_y = 0; | |
| 261 | |||
| 262 | do { | ||
| 263 | ✗ | x = mv[0]; | |
| 264 | ✗ | y = mv[1]; | |
| 265 | |||
| 266 | #if 1 | ||
| 267 | ✗ | for (i = 0; i < 8; i++) | |
| 268 | ✗ | COST_P_MV(x + dia2[i][0], y + dia2[i][1]); | |
| 269 | #else | ||
| 270 | /* this version skips previously examined 3 or 5 locations based on prev origin */ | ||
| 271 | if (dir_x <= 0) | ||
| 272 | COST_P_MV(x - 2, y); | ||
| 273 | if (dir_x <= 0 && dir_y <= 0) | ||
| 274 | COST_P_MV(x - 1, y - 1); | ||
| 275 | if (dir_y <= 0) | ||
| 276 | COST_P_MV(x, y - 2); | ||
| 277 | if (dir_x >= 0 && dir_y <= 0) | ||
| 278 | COST_P_MV(x + 1, y - 1); | ||
| 279 | if (dir_x >= 0) | ||
| 280 | COST_P_MV(x + 2, y); | ||
| 281 | if (dir_x >= 0 && dir_y >= 0) | ||
| 282 | COST_P_MV(x + 1, y + 1); | ||
| 283 | if (dir_y >= 0) | ||
| 284 | COST_P_MV(x, y + 2); | ||
| 285 | if (dir_x <= 0 && dir_y >= 0) | ||
| 286 | COST_P_MV(x - 1, y + 1); | ||
| 287 | |||
| 288 | dir_x = mv[0] - x; | ||
| 289 | dir_y = mv[1] - y; | ||
| 290 | #endif | ||
| 291 | |||
| 292 | ✗ | } while (x != mv[0] || y != mv[1]); | |
| 293 | |||
| 294 | ✗ | for (i = 0; i < 4; i++) | |
| 295 | ✗ | COST_P_MV(x + dia1[i][0], y + dia1[i][1]); | |
| 296 | |||
| 297 | ✗ | return cost_min; | |
| 298 | } | ||
| 299 | |||
| 300 | ✗ | uint64_t ff_me_search_hexbs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 301 | { | ||
| 302 | int x, y; | ||
| 303 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 304 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 305 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 306 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 307 | uint64_t cost, cost_min; | ||
| 308 | int i; | ||
| 309 | |||
| 310 | ✗ | if (!(cost_min = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb, y_mb))) | |
| 311 | ✗ | return cost_min; | |
| 312 | |||
| 313 | do { | ||
| 314 | ✗ | x = mv[0]; | |
| 315 | ✗ | y = mv[1]; | |
| 316 | |||
| 317 | ✗ | for (i = 0; i < 6; i++) | |
| 318 | ✗ | COST_P_MV(x + hex2[i][0], y + hex2[i][1]); | |
| 319 | |||
| 320 | ✗ | } while (x != mv[0] || y != mv[1]); | |
| 321 | |||
| 322 | ✗ | for (i = 0; i < 4; i++) | |
| 323 | ✗ | COST_P_MV(x + dia1[i][0], y + dia1[i][1]); | |
| 324 | |||
| 325 | ✗ | return cost_min; | |
| 326 | } | ||
| 327 | |||
| 328 | /* two subsets of predictors are used | ||
| 329 | me->pred_x|y is set to median of current frame's left, top, top-right | ||
| 330 | set 1: me->preds[0] has: (0, 0), left, top, top-right, collocated block in prev frame | ||
| 331 | set 2: me->preds[1] has: accelerator mv, top, left, right, bottom adj mb of prev frame | ||
| 332 | */ | ||
| 333 | 1200 | uint64_t ff_me_search_epzs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 334 | { | ||
| 335 | int x, y; | ||
| 336 | 1200 | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 337 | 1200 | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 338 | 1200 | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 339 | 1200 | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 340 | uint64_t cost, cost_min; | ||
| 341 | int i; | ||
| 342 | |||
| 343 | 1200 | AVMotionEstPredictor *preds = me_ctx->preds; | |
| 344 | |||
| 345 | 1200 | cost_min = UINT64_MAX; | |
| 346 | |||
| 347 |
6/10✓ Branch 0 taken 1200 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1200 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1200 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1176 times.
✓ Branch 7 taken 24 times.
✓ Branch 9 taken 1176 times.
✗ Branch 10 not taken.
|
1200 | COST_P_MV(x_mb + me_ctx->pred_x, y_mb + me_ctx->pred_y); |
| 348 | |||
| 349 |
2/2✓ Branch 0 taken 5724 times.
✓ Branch 1 taken 1200 times.
|
6924 | for (i = 0; i < preds[0].nb; i++) |
| 350 |
8/10✓ Branch 0 taken 5716 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 5716 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5716 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5658 times.
✓ Branch 7 taken 58 times.
✓ Branch 9 taken 616 times.
✓ Branch 10 taken 5042 times.
|
5724 | COST_P_MV(x_mb + preds[0].mvs[i][0], y_mb + preds[0].mvs[i][1]); |
| 351 | |||
| 352 |
2/2✓ Branch 0 taken 5720 times.
✓ Branch 1 taken 1200 times.
|
6920 | for (i = 0; i < preds[1].nb; i++) |
| 353 |
9/10✓ Branch 0 taken 5714 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5714 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5606 times.
✓ Branch 5 taken 108 times.
✓ Branch 6 taken 5530 times.
✓ Branch 7 taken 76 times.
✓ Branch 9 taken 30 times.
✓ Branch 10 taken 5500 times.
|
5720 | COST_P_MV(x_mb + preds[1].mvs[i][0], y_mb + preds[1].mvs[i][1]); |
| 354 | |||
| 355 | do { | ||
| 356 | 2906 | x = mv[0]; | |
| 357 | 2906 | y = mv[1]; | |
| 358 | |||
| 359 |
2/2✓ Branch 0 taken 11624 times.
✓ Branch 1 taken 2906 times.
|
14530 | for (i = 0; i < 4; i++) |
| 360 |
10/10✓ Branch 0 taken 11352 times.
✓ Branch 1 taken 272 times.
✓ Branch 2 taken 11302 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 11182 times.
✓ Branch 5 taken 120 times.
✓ Branch 6 taken 11028 times.
✓ Branch 7 taken 154 times.
✓ Branch 9 taken 1828 times.
✓ Branch 10 taken 9200 times.
|
11624 | COST_P_MV(x + dia1[i][0], y + dia1[i][1]); |
| 361 | |||
| 362 |
4/4✓ Branch 0 taken 310 times.
✓ Branch 1 taken 2596 times.
✓ Branch 2 taken 1396 times.
✓ Branch 3 taken 1200 times.
|
2906 | } while (x != mv[0] || y != mv[1]); |
| 363 | |||
| 364 | 1200 | return cost_min; | |
| 365 | } | ||
| 366 | |||
| 367 | /* required predictor order: median, (0,0), left, top, top-right | ||
| 368 | rules when mb not available: | ||
| 369 | replace left with (0, 0) | ||
| 370 | replace top-right with top-left | ||
| 371 | replace top two with left | ||
| 372 | repeated can be skipped, if no predictors are used, set me_ctx->pred to (0,0) | ||
| 373 | */ | ||
| 374 | ✗ | uint64_t ff_me_search_umh(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv) | |
| 375 | { | ||
| 376 | int x, y; | ||
| 377 | ✗ | int x_min = FFMAX(me_ctx->x_min, x_mb - me_ctx->search_param); | |
| 378 | ✗ | int y_min = FFMAX(me_ctx->y_min, y_mb - me_ctx->search_param); | |
| 379 | ✗ | int x_max = FFMIN(x_mb + me_ctx->search_param, me_ctx->x_max); | |
| 380 | ✗ | int y_max = FFMIN(y_mb + me_ctx->search_param, me_ctx->y_max); | |
| 381 | uint64_t cost, cost_min; | ||
| 382 | int d, i; | ||
| 383 | int end_x, end_y; | ||
| 384 | |||
| 385 | ✗ | AVMotionEstPredictor *pred = &me_ctx->preds[0]; | |
| 386 | |||
| 387 | ✗ | cost_min = UINT64_MAX; | |
| 388 | |||
| 389 | ✗ | COST_P_MV(x_mb + me_ctx->pred_x, y_mb + me_ctx->pred_y); | |
| 390 | |||
| 391 | ✗ | for (i = 0; i < pred->nb; i++) | |
| 392 | ✗ | COST_P_MV(x_mb + pred->mvs[i][0], y_mb + pred->mvs[i][1]); | |
| 393 | |||
| 394 | // Unsymmetrical-cross Search | ||
| 395 | ✗ | x = mv[0]; | |
| 396 | ✗ | y = mv[1]; | |
| 397 | ✗ | for (d = 1; d <= me_ctx->search_param; d += 2) { | |
| 398 | ✗ | COST_P_MV(x - d, y); | |
| 399 | ✗ | COST_P_MV(x + d, y); | |
| 400 | ✗ | if (d <= me_ctx->search_param / 2) { | |
| 401 | ✗ | COST_P_MV(x, y - d); | |
| 402 | ✗ | COST_P_MV(x, y + d); | |
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | // Uneven Multi-Hexagon-Grid Search | ||
| 407 | ✗ | end_x = FFMIN(mv[0] + 2, x_max); | |
| 408 | ✗ | end_y = FFMIN(mv[1] + 2, y_max); | |
| 409 | ✗ | for (y = FFMAX(y_min, mv[1] - 2); y <= end_y; y++) | |
| 410 | ✗ | for (x = FFMAX(x_min, mv[0] - 2); x <= end_x; x++) | |
| 411 | ✗ | COST_P_MV(x, y); | |
| 412 | |||
| 413 | ✗ | x = mv[0]; | |
| 414 | ✗ | y = mv[1]; | |
| 415 | ✗ | for (d = 1; d <= me_ctx->search_param / 4; d++) | |
| 416 | ✗ | for (i = 1; i < 16; i++) | |
| 417 | ✗ | COST_P_MV(x + hex4[i][0] * d, y + hex4[i][1] * d); | |
| 418 | |||
| 419 | // Extended Hexagon-based Search | ||
| 420 | do { | ||
| 421 | ✗ | x = mv[0]; | |
| 422 | ✗ | y = mv[1]; | |
| 423 | |||
| 424 | ✗ | for (i = 0; i < 6; i++) | |
| 425 | ✗ | COST_P_MV(x + hex2[i][0], y + hex2[i][1]); | |
| 426 | |||
| 427 | ✗ | } while (x != mv[0] || y != mv[1]); | |
| 428 | |||
| 429 | ✗ | for (i = 0; i < 4; i++) | |
| 430 | ✗ | COST_P_MV(x + dia1[i][0], y + dia1[i][1]); | |
| 431 | |||
| 432 | ✗ | return cost_min; | |
| 433 | } | ||
| 434 |