1// -*- c++ -*- 2 3 // First, get and save our possible Bob values 4 // Assume our pixels are laid out as follows with x the calc'd bob value 5 // and the other pixels are from the current field 6 // 7 // j a b c k current field 8 // x calculated line 9 // m d e f n current field 10 // 11 // we calc the bob value luma value as: 12 // if |j - n| < Thres && |a - m| > Thres 13 // avg(j,n) 14 // end if 15 // if |k - m| < Thres && |c - n| > Thres 16 // avg(k,m) 17 // end if 18 // if |c - d| < Thres && |b - f| > Thres 19 // avg(c,d) 20 // end if 21 // if |a - f| < Thres && |b - d| > Thres 22 // avg(a,f) 23 // end if 24 // if |b - e| < Thres 25 // avg(b,e) 26 // end if 27 // pickup any thing not yet set with avg(b,e) 28 29#ifndef IS_C 30 31 // j, n 32 "pxor %%mm5, %%mm5\n\t" 33 "pxor %%mm6, %%mm6\n\t" 34 "pxor %%mm7, %%mm7\n\t" 35 36 "movq -2(%%"XBX"), %%mm0\n\t" // value a from top left 37 "movq -4(%%"XBX", %%"XCX"), %%mm1\n\t" // value m from bottom right 38 39 "movq %%mm0, %%mm3\n\t" 40 "psubusb %%mm1, %%mm3\n\t" 41 "psubusb %%mm0, %%mm1\n\t" 42 "por %%mm1, %%mm3\n\t" // abs(a,m) 43 44 "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(a,m) > Thres else 0 45 "pxor %%mm4, %%mm4\n\t" 46 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(a,m) < Thres, else 00 47 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(a,m) > Thres, else 00 48 49 50 "movq -4(%%"XBX"), %%mm0\n\t" // value j 51 "movq 4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n 52 "movq %%mm0, %%mm2\n\t" 53 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(j,n) 54 "movq %%mm0, %%mm3\n\t" 55 "psubusb %%mm1, %%mm0\n\t" 56 "psubusb %%mm3, %%mm1\n\t" 57 "por %%mm1, %%mm0\n\t" // abs(j,n) 58 59 "movq %%mm0, %%mm1\n\t" 60 "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(j,n) > Thres else 0 61 "pxor %%mm3, %%mm3\n\t" 62 "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(j,n) < Thres, else 00 63 64 "pand %%mm4, %%mm1\n\t" 65 "pand %%mm1, %%mm2\n\t" 66 "pand %%mm1, %%mm0\n\t" 67 68 "movq %%mm1, %%mm3\n\t" 69 "pxor %%mm5, %%mm3\n\t" 70 "pand %%mm3, %%mm6\n\t" 71 "pand %%mm3, %%mm7\n\t" 72 "pand %%mm3, %%mm5\n\t" 73 74 "por %%mm1, %%mm5\n\t" 75 "por %%mm2, %%mm6\n\t" 76 "por %%mm0, %%mm7\n\t" 77 78 // k & m 79 "movq 2(%%"XBX"), %%mm0\n\t" // value c from top left 80 "movq 4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n from bottom right 81 82 "movq %%mm0, %%mm3\n\t" 83 "psubusb %%mm1, %%mm3\n\t" 84 "psubusb %%mm0, %%mm1\n\t" 85 "por %%mm1, %%mm3\n\t" // abs(c,n) 86 87 "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(c,n) > Thres else 0 88 "pxor %%mm4, %%mm4\n\t" 89 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(c,n) < Thres, else 00 90 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(c,n) > Thres, else 00 91 92 93 "movq 4(%%"XBX"), %%mm0\n\t" // value k 94 "movq -4(%%"XBX", %%"XCX"), %%mm1\n\t" // value m 95 "movq %%mm0, %%mm2\n\t" 96 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(k,m) 97 "movq %%mm0, %%mm3\n\t" 98 "psubusb %%mm1, %%mm0\n\t" 99 "psubusb %%mm3, %%mm1\n\t" 100 "por %%mm1, %%mm0\n\t" // abs(k,m) 101 102 "movq %%mm0, %%mm1\n\t" 103 "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(k,m) > Thres else 0 104 "pxor %%mm3, %%mm3\n\t" 105 "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(k,m) < Thres, else 00 106 107 "pand %%mm4, %%mm1\n\t" 108 109 "pand %%mm1, %%mm2\n\t" 110 "pand %%mm1, %%mm0\n\t" 111 112 "movq %%mm1, %%mm3\n\t" 113 "pxor %%mm5, %%mm3\n\t" 114 "pand %%mm3, %%mm6\n\t" 115 "pand %%mm3, %%mm7\n\t" 116 "pand %%mm3, %%mm5\n\t" 117 118 "por %%mm1, %%mm5\n\t" 119 "por %%mm2, %%mm6\n\t" 120 "por %%mm0, %%mm7\n\t" 121 122 123 // c & d 124 "movq (%%"XBX"), %%mm0\n\t" // value b from top left 125 "movq 2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f from bottom right 126 127 "movq %%mm0, %%mm3\n\t" 128 "psubusb %%mm1, %%mm3\n\t" 129 "psubusb %%mm0, %%mm1\n\t" 130 "por %%mm1, %%mm3\n\t" // abs(b,f) 131 132 "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,f) > Thres else 0 133 "pxor %%mm4, %%mm4\n\t" 134 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,f) < Thres, else 00 135 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,f) > Thres, else 00 136 137 "movq 2(%%"XBX"), %%mm0\n\t" // value c 138 "movq -2(%%"XBX", %%"XCX"), %%mm1\n\t" // value d 139 "movq %%mm0, %%mm2\n\t" 140 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(c,d) 141 "movq %%mm0, %%mm3\n\t" 142 "psubusb %%mm1, %%mm0\n\t" 143 "psubusb %%mm3, %%mm1\n\t" 144 "por %%mm1, %%mm0\n\t" // abs(c,d) 145 146 "movq %%mm0, %%mm1\n\t" 147 "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(c,d) > Thres else 0 148 "pxor %%mm3, %%mm3\n\t" 149 "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(c,d) < Thres, else 00 150 151 "pand %%mm4, %%mm1\n\t" 152 153 "pand %%mm1, %%mm2\n\t" 154 "pand %%mm1, %%mm0\n\t" 155 156 "movq %%mm1, %%mm3\n\t" 157 "pxor %%mm5, %%mm3\n\t" 158 "pand %%mm3, %%mm6\n\t" 159 "pand %%mm3, %%mm7\n\t" 160 "pand %%mm3, %%mm5\n\t" 161 162 "por %%mm1, %%mm5\n\t" 163 "por %%mm2, %%mm6\n\t" 164 "por %%mm0, %%mm7\n\t" 165 166 // a & f 167 "movq (%%"XBX"), %%mm0\n\t" // value b from top left 168 "movq -2(%%"XBX", %%"XCX"), %%mm1\n\t" // value d from bottom right 169 170 "movq %%mm0, %%mm3\n\t" 171 "psubusb %%mm1, %%mm3\n\t" 172 "psubusb %%mm0, %%mm1\n\t" 173 "por %%mm1, %%mm3\n\t" // abs(b,d) 174 175 "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,d) > Thres else 0 176 "pxor %%mm4, %%mm4\n\t" 177 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,d) < Thres, else 00 178 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,d) > Thres, else 00 179 180 "movq -2(%%"XBX"), %%mm0\n\t" // value a 181 "movq 2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f 182 "movq %%mm0, %%mm2\n\t" 183 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(a,f) 184 "movq %%mm0, %%mm3\n\t" 185 "psubusb %%mm1, %%mm0\n\t" 186 "psubusb %%mm3, %%mm1\n\t" 187 "por %%mm1, %%mm0\n\t" // abs(a,f) 188 189 "movq %%mm0, %%mm1\n\t" 190 "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(a,f) > Thres else 0 191 "pxor %%mm3, %%mm3\n\t" 192 "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(a,f) < Thres, else 00 193 194 "pand %%mm4, %%mm1\n\t" 195 196 "pand %%mm1, %%mm2\n\t" 197 "pand %%mm1, %%mm0\n\t" 198 199 "movq %%mm1, %%mm3\n\t" 200 "pxor %%mm5, %%mm3\n\t" 201 "pand %%mm3, %%mm6\n\t" 202 "pand %%mm3, %%mm7\n\t" 203 "pand %%mm3, %%mm5\n\t" 204 205 "por %%mm1, %%mm5\n\t" 206 "por %%mm2, %%mm6\n\t" 207 "por %%mm0, %%mm7\n\t" 208 209 "pand "_YMask", %%mm5\n\t" // mask out chroma from here 210 "pand "_YMask", %%mm6\n\t" // mask out chroma from here 211 "pand "_YMask", %%mm7\n\t" // mask out chroma from here 212 213 // b,e 214 "movq (%%"XBX"), %%mm0\n\t" // value b from top 215 "movq (%%"XBX", %%"XCX"), %%mm1\n\t" // value e from bottom 216 "movq %%mm0, %%mm2\n\t" 217 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e) 218 "movq %%mm0, %%mm3\n\t" 219 "psubusb %%mm1, %%mm0\n\t" 220 "psubusb %%mm3, %%mm1\n\t" 221 "por %%mm1, %%mm0\n\t" // abs(b,e) 222 223 "movq %%mm0, %%mm1\n\t" 224 "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(b,e) > Thres else 0 225 "pxor %%mm3, %%mm3\n\t" 226 "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(b,e) < Thres, else 00 227 228 "pand %%mm1, %%mm2\n\t" 229 "pand %%mm1, %%mm0\n\t" 230 231 "movq %%mm1, %%mm3\n\t" 232 "pxor %%mm5, %%mm3\n\t" 233 "pand %%mm3, %%mm6\n\t" 234 "pand %%mm3, %%mm7\n\t" 235 "pand %%mm3, %%mm5\n\t" 236 237 "por %%mm1, %%mm5\n\t" 238 "por %%mm2, %%mm6\n\t" 239 "por %%mm0, %%mm7\n\t" 240 241 // bob in any leftovers 242 "movq (%%"XBX"), %%mm0\n\t" // value b from top 243 "movq (%%"XBX", %%"XCX"), %%mm1\n\t" // value e from bottom 244 245 246// We will also calc here the max/min values to later limit comb 247// so the max excursion will not exceed the Max_Comb constant 248 249#ifdef SKIP_SEARCH 250 "movq %%mm0, %%mm2\n\t" 251// pminub %%mm2, %%mm1 252 V_PMINUB ("%%mm2", "%%mm1", "%%mm4") 253 254// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this 255 V_PMAXUB ("%%mm6", "%%mm2") 256 "movq %%mm0, %%mm2\n\t" 257 V_PMAXUB ("%%mm2", "%%mm1") 258// pminub %%mm6, %%mm2 // clip our current results so far to be below this 259 V_PMINUB ("%%mm6", "%%mm2", "%%mm4") 260 261#else 262 "movq %%mm0, %%mm2\n\t" 263 "movq (%%"XAX"), %%mm4\n\t" 264 "psubusb %%mm4, %%mm2\n\t" 265 "psubusb %%mm0, %%mm4\n\t" 266 "por %%mm2, %%mm4\n\t" // abs diff 267 268 "movq %%mm1, %%mm2\n\t" 269 "movq (%%"XAX", %%"XCX"), %%mm3\n\t" 270 "psubusb %%mm3, %%mm2\n\t" 271 "psubusb %%mm1, %%mm3\n\t" 272 "por %%mm2, %%mm3\n\t" // abs diff 273// pmaxub %%mm3, %%mm4 // top or bottom pixel moved most 274 V_PMAXUB ("%%mm3", "%%mm4") // top or bottom pixel moved most 275 "psubusb "_DiffThres", %%mm3\n\t" // moved more than allowed? or goes to 0? 276 "pxor %%mm4, %%mm4\n\t" 277 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where low motion, else high motion 278 279 "movq %%mm0, %%mm2\n\t" 280// pminub %%mm2, %%mm1 281 V_PMINUB ("%%mm2", "%%mm1", "%%mm4") 282 283// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this 284 V_PMAXUB ("%%mm6", "%%mm2") 285 286 "psubusb %%mm3, %%mm2\n\t" // maybe decrease it to 0000.. if no surround motion 287 "movq %%mm2, "_Min_Vals"\n\t" 288 289 "movq %%mm0, %%mm2\n\t" 290 V_PMAXUB ("%%mm2", "%%mm1") 291// pminub %%mm6, %%mm2 // clip our current results so far to be below this 292 V_PMINUB ("%%mm6", "%%mm2", "%%mm4") 293 "paddusb %%mm3, %%mm2\n\t" // maybe increase it to ffffff if no surround motion 294 "movq %%mm2, "_Max_Vals"\n\t" 295#endif 296 297 "movq %%mm0, %%mm2\n\t" 298// pavgb %%mm2, %%mm1 // avg(b,e) 299 V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e) 300 301 "movq %%mm0, %%mm3\n\t" 302 "psubusb %%mm1, %%mm3\n\t" 303 "psubusb %%mm0, %%mm1\n\t" 304 "por %%mm1, %%mm3\n\t" // abs(b,e) 305 "movq %%mm3, %%mm1\n\t" // keep copy of diffs 306 307 "pxor %%mm4, %%mm4\n\t" 308 "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 309 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 310 "pcmpeqb %%mm0, %%mm0\n\t" 311 "pandn %%mm0, %%mm5\n\t" 312 "por %%mm5, %%mm3\n\t" 313 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 314 315 "pand %%mm3, %%mm1\n\t" 316 "pand %%mm3, %%mm2\n\t" 317 318 "pand %%mm4, %%mm6\n\t" 319 "pand %%mm4, %%mm7\n\t" 320 321 "por %%mm2, %%mm6\n\t" // our x2 value 322 "por %%mm1, %%mm7\n\t" // our x2 diffs 323 "movq %%mm7, %%mm4\n\t" // save as bob uncertainty indicator 324 325#else 326 327 diff[0] = -1; 328 diff[1] = -1; 329 best[0] = 0; 330 best[1] = 0; 331 // j, n 332 if (ABS (pBob[-2] - pBob[src_pitch2 - 4]) < DiffThres && 333 ABS (pBob[-4] - pBob[src_pitch2 + 4]) > DiffThres) { 334 best[0] = (pBob[-2] + pBob[src_pitch2 - 4]) / 2; 335 diff[0] = ABS (pBob[-2] - pBob[src_pitch2 - 4]); 336 } 337 if (ABS (pBob[-1] - pBob[src_pitch2 - 3]) < DiffThres && 338 ABS (pBob[-3] - pBob[src_pitch2 + 5]) > DiffThres) { 339 best[1] = (pBob[-1] + pBob[src_pitch2 - 3]) / 2; 340 diff[1] = ABS (pBob[-1] - pBob[src_pitch2 - 3]); 341 } 342 343 // k & m 344 if (ABS (pBob[2] - pBob[src_pitch2 + 4]) < DiffThres && 345 ABS (pBob[4] - pBob[src_pitch2 - 4]) > DiffThres) { 346 best[0] = (pBob[4] + pBob[src_pitch2 - 4]) / 2; 347 diff[0] = ABS (pBob[4] - pBob[src_pitch2 - 4]); 348 } 349 350 if (ABS (pBob[3] - pBob[src_pitch2 + 5]) < DiffThres && 351 ABS (pBob[5] - pBob[src_pitch2 - 3]) > DiffThres) { 352 best[1] = (pBob[5] + pBob[src_pitch2 - 3]) / 2; 353 diff[1] = ABS (pBob[5] - pBob[src_pitch2 - 3]); 354 } 355 356 // c & d 357 if (ABS (pBob[0] - pBob[src_pitch2 + 2]) < DiffThres && 358 ABS (pBob[2] - pBob[src_pitch2 - 2]) > DiffThres) { 359 best[0] = (pBob[2] + pBob[src_pitch2 - 2]) / 2; 360 diff[0] = ABS (pBob[2] - pBob[src_pitch2 - 2]); 361 } 362 363 if (ABS (pBob[1] - pBob[src_pitch2 + 3]) < DiffThres && 364 ABS (pBob[3] - pBob[src_pitch2 - 1]) > DiffThres) { 365 best[1] = (pBob[3] + pBob[src_pitch2 - 1]) / 2; 366 diff[1] = ABS (pBob[3] - pBob[src_pitch2 - 1]); 367 } 368 369 // a & f 370 if (ABS (pBob[0] - pBob[src_pitch2 - 2]) < DiffThres && 371 ABS (pBob[-2] - pBob[src_pitch2 + 2]) > DiffThres) { 372 best[0] = (pBob[-2] + pBob[src_pitch2 + 2]) / 2; 373 diff[0] = ABS (pBob[-2] - pBob[src_pitch2 + 2]); 374 } 375 376 if (ABS (pBob[1] - pBob[src_pitch2 - 1]) < DiffThres && 377 ABS (pBob[-1] - pBob[src_pitch2 + 3]) > DiffThres) { 378 best[1] = (pBob[-1] + pBob[src_pitch2 + 3]) / 2; 379 diff[1] = ABS (pBob[-1] - pBob[src_pitch2 + 3]); 380 } 381 382 // b,e 383 if (ABS (pBob[0] - pBob[src_pitch2]) < DiffThres) { 384 best[0] = (pBob[0] + pBob[src_pitch2]) / 2; 385 diff[0] = ABS (pBob[0] - pBob[src_pitch2]); 386 } 387 388 if (ABS (pBob[1] - pBob[src_pitch2 + 1]) < DiffThres) { 389 best[1] = (pBob[1] + pBob[src_pitch2 + 1]) / 2; 390 diff[1] = ABS (pBob[1] - pBob[src_pitch2 + 1]); 391 } 392 393 394// We will also calc here the max/min values to later limit comb 395// so the max excursion will not exceed the Max_Comb constant 396 397#ifdef SKIP_SEARCH 398 best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0])); 399 best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1])); 400#else 401 mov[0] = MAX (ABS (pBob[0] - pBobP[0]), ABS (pBob[src_pitch2] - pBobP[src_pitch2])); 402 mov[1] = MAX (ABS (pBob[1] - pBobP[1]), ABS (pBob[src_pitch2 + 1] - pBobP[src_pitch2 + 1])); 403 404 MinVals[0] = 0; 405 MinVals[1] = 0; 406 MaxVals[0] = 255; 407 MaxVals[1] = 255; 408 if (mov[0] > DiffThres) { 409 MinVals[0] = MAX (MIN (pBob[0], pBob[src_pitch2]), best[0]); 410 MaxVals[0] = MIN (MAX (pBob[0], pBob[src_pitch2]), best[0]); 411 } 412 413 if (mov[1] > DiffThres) { 414 MinVals[1] = MAX (MIN (pBob[1], pBob[src_pitch2+1]), best[1]); 415 MaxVals[1] = MIN (MAX (pBob[1], pBob[src_pitch2+1]), best[1]); 416 } 417 418 best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0])); 419 best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1])); 420#endif 421 avg[0] = (pBob[src_pitch2] + pBob[0]) / 2; 422 avg[1] = (pBob[src_pitch2 + 1] + pBob[1]) / 2; 423 diff2[0] = ABS (pBob[src_pitch2 + 1] - pBob[1]); 424 diff2[1] = ABS (pBob[src_pitch2 + 1] - pBob[1]); 425 426 if (diff[0] == -1 || diff2[0] < diff[0]) { 427 best[0] = avg[0]; 428 diff[0] = diff2[0]; 429 } 430 431 if (diff[1] == -1 || diff2[1] < diff[1]) { 432 best[1] = avg[1]; 433 diff[1] = diff2[1]; 434 } 435#endif 436