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