1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #include "mp4def.h" 19 #include "mp4lib_int.h" 20 21 #include "sad_inline.h" 22 23 #define Cached_lx 176 24 25 #ifdef _SAD_STAT 26 ULong num_sad_MB = 0; 27 ULong num_sad_Blk = 0; 28 ULong num_sad_MB_call = 0; 29 ULong num_sad_Blk_call = 0; 30 31 #define NUM_SAD_MB_CALL() num_sad_MB_call++ 32 #define NUM_SAD_MB() num_sad_MB++ 33 #define NUM_SAD_BLK_CALL() num_sad_Blk_call++ 34 #define NUM_SAD_BLK() num_sad_Blk++ 35 36 #else 37 38 #define NUM_SAD_MB_CALL() 39 #define NUM_SAD_MB() 40 #define NUM_SAD_BLK_CALL() 41 #define NUM_SAD_BLK() 42 43 #endif 44 45 46 /* consist of 47 Int SAD_Macroblock_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) 48 Int SAD_MB_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) 49 Int SAD_MB_HTFM(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) 50 Int SAD_Block_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) 51 Int SAD_Blk_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) 52 Int SAD_MB_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) 53 Int SAD_MB_PAD1(UChar *ref,UChar *cur,Int dmin,Int lx,Int *rep); 54 Int SAD_MB_PADDING_HTFM_Collect(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) 55 Int SAD_MB_PADDING_HTFM(UChar *ref,UChar *cur,Int dmin,Int lx,void *vptr) 56 */ 57 58 59 #ifdef __cplusplus 60 extern "C" 61 { 62 #endif 63 64 Int SAD_MB_PAD1(UChar *ref, UChar *cur, Int dmin, Int lx, Int *rep); 65 66 67 /*================================================================== 68 Function: SAD_Macroblock 69 Date: 09/07/2000 70 Purpose: Compute SAD 16x16 between blk and ref. 71 To do: Uniform subsampling will be inserted later! 72 Hypothesis Testing Fast Matching to be used later! 73 Changes: 74 11/7/00: implemented MMX 75 1/24/01: implemented SSE 76 ==================================================================*/ 77 /********** C ************/ SAD_Macroblock_C(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)78 Int SAD_Macroblock_C(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) 79 { 80 int32 x10; 81 Int dmin = (ULong)dmin_lx >> 16; 82 Int lx = dmin_lx & 0xFFFF; 83 84 OSCL_UNUSED_ARG(extra_info); 85 86 NUM_SAD_MB_CALL(); 87 88 x10 = simd_sad_mb(ref, blk, dmin, lx); 89 90 return x10; 91 } 92 93 #ifdef HTFM /* HTFM with uniform subsampling implementation, 2/28/01 */ 94 /*=============================================================== 95 Function: SAD_MB_HTFM_Collect and SAD_MB_HTFM 96 Date: 3/2/1 97 Purpose: Compute the SAD on a 16x16 block using 98 uniform subsampling and hypothesis testing fast matching 99 for early dropout. SAD_MB_HP_HTFM_Collect is to collect 100 the statistics to compute the thresholds to be used in 101 SAD_MB_HP_HTFM. 102 Input/Output: 103 Changes: 104 ===============================================================*/ 105 SAD_MB_HTFM_Collect(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)106 Int SAD_MB_HTFM_Collect(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) 107 { 108 Int i; 109 Int sad = 0; 110 UChar *p1; 111 Int lx4 = (dmin_lx << 2) & 0x3FFFC; 112 ULong cur_word; 113 Int saddata[16], tmp, tmp2; /* used when collecting flag (global) is on */ 114 Int difmad; 115 HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info; 116 Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg); 117 UInt *countbreak = &(htfm_stat->countbreak); 118 Int *offsetRef = htfm_stat->offsetRef; 119 120 NUM_SAD_MB_CALL(); 121 122 blk -= 4; 123 for (i = 0; i < 16; i++) 124 { 125 p1 = ref + offsetRef[i]; 126 cur_word = *((ULong*)(blk += 4)); 127 tmp = p1[12]; 128 tmp2 = (cur_word >> 24) & 0xFF; 129 sad = SUB_SAD(sad, tmp, tmp2); 130 tmp = p1[8]; 131 tmp2 = (cur_word >> 16) & 0xFF; 132 sad = SUB_SAD(sad, tmp, tmp2); 133 tmp = p1[4]; 134 tmp2 = (cur_word >> 8) & 0xFF; 135 sad = SUB_SAD(sad, tmp, tmp2); 136 tmp = p1[0]; 137 p1 += lx4; 138 tmp2 = (cur_word & 0xFF); 139 sad = SUB_SAD(sad, tmp, tmp2); 140 141 cur_word = *((ULong*)(blk += 4)); 142 tmp = p1[12]; 143 tmp2 = (cur_word >> 24) & 0xFF; 144 sad = SUB_SAD(sad, tmp, tmp2); 145 tmp = p1[8]; 146 tmp2 = (cur_word >> 16) & 0xFF; 147 sad = SUB_SAD(sad, tmp, tmp2); 148 tmp = p1[4]; 149 tmp2 = (cur_word >> 8) & 0xFF; 150 sad = SUB_SAD(sad, tmp, tmp2); 151 tmp = p1[0]; 152 p1 += lx4; 153 tmp2 = (cur_word & 0xFF); 154 sad = SUB_SAD(sad, tmp, tmp2); 155 156 cur_word = *((ULong*)(blk += 4)); 157 tmp = p1[12]; 158 tmp2 = (cur_word >> 24) & 0xFF; 159 sad = SUB_SAD(sad, tmp, tmp2); 160 tmp = p1[8]; 161 tmp2 = (cur_word >> 16) & 0xFF; 162 sad = SUB_SAD(sad, tmp, tmp2); 163 tmp = p1[4]; 164 tmp2 = (cur_word >> 8) & 0xFF; 165 sad = SUB_SAD(sad, tmp, tmp2); 166 tmp = p1[0]; 167 p1 += lx4; 168 tmp2 = (cur_word & 0xFF); 169 sad = SUB_SAD(sad, tmp, tmp2); 170 171 cur_word = *((ULong*)(blk += 4)); 172 tmp = p1[12]; 173 tmp2 = (cur_word >> 24) & 0xFF; 174 sad = SUB_SAD(sad, tmp, tmp2); 175 tmp = p1[8]; 176 tmp2 = (cur_word >> 16) & 0xFF; 177 sad = SUB_SAD(sad, tmp, tmp2); 178 tmp = p1[4]; 179 tmp2 = (cur_word >> 8) & 0xFF; 180 sad = SUB_SAD(sad, tmp, tmp2); 181 tmp = p1[0]; 182 p1 += lx4; 183 tmp2 = (cur_word & 0xFF); 184 sad = SUB_SAD(sad, tmp, tmp2); 185 186 NUM_SAD_MB(); 187 188 saddata[i] = sad; 189 190 if (i > 0) 191 { 192 if ((ULong)sad > ((ULong)dmin_lx >> 16)) 193 { 194 difmad = saddata[0] - ((saddata[1] + 1) >> 1); 195 (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); 196 (*countbreak)++; 197 return sad; 198 } 199 } 200 } 201 202 difmad = saddata[0] - ((saddata[1] + 1) >> 1); 203 (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); 204 (*countbreak)++; 205 return sad; 206 } 207 SAD_MB_HTFM(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)208 Int SAD_MB_HTFM(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) 209 { 210 Int sad = 0; 211 UChar *p1; 212 213 Int i; 214 Int tmp, tmp2; 215 Int lx4 = (dmin_lx << 2) & 0x3FFFC; 216 Int sadstar = 0, madstar; 217 Int *nrmlz_th = (Int*) extra_info; 218 Int *offsetRef = (Int*) extra_info + 32; 219 ULong cur_word; 220 221 madstar = (ULong)dmin_lx >> 20; 222 223 NUM_SAD_MB_CALL(); 224 225 blk -= 4; 226 for (i = 0; i < 16; i++) 227 { 228 p1 = ref + offsetRef[i]; 229 cur_word = *((ULong*)(blk += 4)); 230 tmp = p1[12]; 231 tmp2 = (cur_word >> 24) & 0xFF; 232 sad = SUB_SAD(sad, tmp, tmp2); 233 tmp = p1[8]; 234 tmp2 = (cur_word >> 16) & 0xFF; 235 sad = SUB_SAD(sad, tmp, tmp2); 236 tmp = p1[4]; 237 tmp2 = (cur_word >> 8) & 0xFF; 238 sad = SUB_SAD(sad, tmp, tmp2); 239 tmp = p1[0]; 240 p1 += lx4; 241 tmp2 = (cur_word & 0xFF); 242 sad = SUB_SAD(sad, tmp, tmp2); 243 244 cur_word = *((ULong*)(blk += 4)); 245 tmp = p1[12]; 246 tmp2 = (cur_word >> 24) & 0xFF; 247 sad = SUB_SAD(sad, tmp, tmp2); 248 tmp = p1[8]; 249 tmp2 = (cur_word >> 16) & 0xFF; 250 sad = SUB_SAD(sad, tmp, tmp2); 251 tmp = p1[4]; 252 tmp2 = (cur_word >> 8) & 0xFF; 253 sad = SUB_SAD(sad, tmp, tmp2); 254 tmp = p1[0]; 255 p1 += lx4; 256 tmp2 = (cur_word & 0xFF); 257 sad = SUB_SAD(sad, tmp, tmp2); 258 259 cur_word = *((ULong*)(blk += 4)); 260 tmp = p1[12]; 261 tmp2 = (cur_word >> 24) & 0xFF; 262 sad = SUB_SAD(sad, tmp, tmp2); 263 tmp = p1[8]; 264 tmp2 = (cur_word >> 16) & 0xFF; 265 sad = SUB_SAD(sad, tmp, tmp2); 266 tmp = p1[4]; 267 tmp2 = (cur_word >> 8) & 0xFF; 268 sad = SUB_SAD(sad, tmp, tmp2); 269 tmp = p1[0]; 270 p1 += lx4; 271 tmp2 = (cur_word & 0xFF); 272 sad = SUB_SAD(sad, tmp, tmp2); 273 274 cur_word = *((ULong*)(blk += 4)); 275 tmp = p1[12]; 276 tmp2 = (cur_word >> 24) & 0xFF; 277 sad = SUB_SAD(sad, tmp, tmp2); 278 tmp = p1[8]; 279 tmp2 = (cur_word >> 16) & 0xFF; 280 sad = SUB_SAD(sad, tmp, tmp2); 281 tmp = p1[4]; 282 tmp2 = (cur_word >> 8) & 0xFF; 283 sad = SUB_SAD(sad, tmp, tmp2); 284 tmp = p1[0]; 285 p1 += lx4; 286 tmp2 = (cur_word & 0xFF); 287 sad = SUB_SAD(sad, tmp, tmp2); 288 289 NUM_SAD_MB(); 290 291 sadstar += madstar; 292 if (((ULong)sad <= ((ULong)dmin_lx >> 16)) && (sad <= (sadstar - *nrmlz_th++))) 293 ; 294 else 295 return 65536; 296 } 297 298 return sad; 299 } 300 #endif /* HTFM */ 301 302 #ifndef NO_INTER4V 303 /*================================================================== 304 Function: SAD_Block 305 Date: 09/07/2000 306 Purpose: Compute SAD 16x16 between blk and ref. 307 To do: Uniform subsampling will be inserted later! 308 Hypothesis Testing Fast Matching to be used later! 309 Changes: 310 11/7/00: implemented MMX 311 1/24/01: implemented SSE 312 ==================================================================*/ 313 /********** C ************/ SAD_Block_C(UChar * ref,UChar * blk,Int dmin,Int lx,void *)314 Int SAD_Block_C(UChar *ref, UChar *blk, Int dmin, Int lx, void *) 315 { 316 Int sad = 0; 317 318 Int i; 319 UChar *ii; 320 Int *kk; 321 Int tmp, tmp2, tmp3, mask = 0xFF; 322 Int width = (lx - 32); 323 324 NUM_SAD_BLK_CALL(); 325 326 ii = ref; 327 kk = (Int*)blk; /* assuming word-align for blk */ 328 for (i = 0; i < 8; i++) 329 { 330 tmp3 = kk[1]; 331 tmp = ii[7]; 332 tmp2 = (UInt)tmp3 >> 24; 333 sad = SUB_SAD(sad, tmp, tmp2); 334 tmp = ii[6]; 335 tmp2 = (tmp3 >> 16) & mask; 336 sad = SUB_SAD(sad, tmp, tmp2); 337 tmp = ii[5]; 338 tmp2 = (tmp3 >> 8) & mask; 339 sad = SUB_SAD(sad, tmp, tmp2); 340 tmp = ii[4]; 341 tmp2 = tmp3 & mask; 342 sad = SUB_SAD(sad, tmp, tmp2); 343 tmp3 = *kk; 344 kk += (width >> 2); 345 tmp = ii[3]; 346 tmp2 = (UInt)tmp3 >> 24; 347 sad = SUB_SAD(sad, tmp, tmp2); 348 tmp = ii[2]; 349 tmp2 = (tmp3 >> 16) & mask; 350 sad = SUB_SAD(sad, tmp, tmp2); 351 tmp = ii[1]; 352 tmp2 = (tmp3 >> 8) & mask; 353 sad = SUB_SAD(sad, tmp, tmp2); 354 tmp = *ii; 355 ii += lx; 356 tmp2 = tmp3 & mask; 357 sad = SUB_SAD(sad, tmp, tmp2); 358 359 NUM_SAD_BLK(); 360 361 if (sad > dmin) 362 return sad; 363 } 364 365 return sad; 366 } 367 368 #endif /* NO_INTER4V */ 369 370 #ifdef __cplusplus 371 } 372 #endif 373 374 375 376