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 "avcenc_lib.h" 19 #include "sad_inline.h" 20 21 #define Cached_lx 176 22 23 #ifdef _SAD_STAT 24 uint32 num_sad_MB = 0; 25 uint32 num_sad_Blk = 0; 26 uint32 num_sad_MB_call = 0; 27 uint32 num_sad_Blk_call = 0; 28 29 #define NUM_SAD_MB_CALL() num_sad_MB_call++ 30 #define NUM_SAD_MB() num_sad_MB++ 31 #define NUM_SAD_BLK_CALL() num_sad_Blk_call++ 32 #define NUM_SAD_BLK() num_sad_Blk++ 33 34 #else 35 36 #define NUM_SAD_MB_CALL() 37 #define NUM_SAD_MB() 38 #define NUM_SAD_BLK_CALL() 39 #define NUM_SAD_BLK() 40 41 #endif 42 43 44 /* consist of 45 int AVCSAD_Macroblock_C(uint8 *ref,uint8 *blk,int dmin,int lx,void *extra_info) 46 int AVCSAD_MB_HTFM_Collect(uint8 *ref,uint8 *blk,int dmin,int lx,void *extra_info) 47 int AVCSAD_MB_HTFM(uint8 *ref,uint8 *blk,int dmin,int lx,void *extra_info) 48 */ 49 50 51 /*================================================================== 52 Function: SAD_Macroblock 53 Date: 09/07/2000 54 Purpose: Compute SAD 16x16 between blk and ref. 55 To do: Uniform subsampling will be inserted later! 56 Hypothesis Testing Fast Matching to be used later! 57 Changes: 58 11/7/00: implemented MMX 59 1/24/01: implemented SSE 60 ==================================================================*/ 61 /********** C ************/ 62 int AVCSAD_Macroblock_C(uint8 *ref, uint8 *blk, int dmin_lx, void *extra_info) 63 { 64 (void)(extra_info); 65 66 int32 x10; 67 int dmin = (uint32)dmin_lx >> 16; 68 int lx = dmin_lx & 0xFFFF; 69 70 NUM_SAD_MB_CALL(); 71 72 x10 = simd_sad_mb(ref, blk, dmin, lx); 73 74 return x10; 75 } 76 77 #ifdef HTFM /* HTFM with uniform subsampling implementation 2/28/01 */ 78 /*=============================================================== 79 Function: AVCAVCSAD_MB_HTFM_Collect and AVCSAD_MB_HTFM 80 Date: 3/2/1 81 Purpose: Compute the SAD on a 16x16 block using 82 uniform subsampling and hypothesis testing fast matching 83 for early dropout. SAD_MB_HP_HTFM_Collect is to collect 84 the statistics to compute the thresholds to be used in 85 SAD_MB_HP_HTFM. 86 Input/Output: 87 Changes: 88 ===============================================================*/ 89 90 int AVCAVCSAD_MB_HTFM_Collect(uint8 *ref, uint8 *blk, int dmin_lx, void *extra_info) 91 { 92 int i; 93 int sad = 0; 94 uint8 *p1; 95 int lx4 = (dmin_lx << 2) & 0x3FFFC; 96 uint32 cur_word; 97 int saddata[16], tmp, tmp2; /* used when collecting flag (global) is on */ 98 int difmad; 99 int madstar; 100 HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info; 101 int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg); 102 uint *countbreak = &(htfm_stat->countbreak); 103 int *offsetRef = htfm_stat->offsetRef; 104 105 madstar = (uint32)dmin_lx >> 20; 106 107 NUM_SAD_MB_CALL(); 108 109 blk -= 4; 110 for (i = 0; i < 16; i++) 111 { 112 p1 = ref + offsetRef[i]; 113 cur_word = *((uint32*)(blk += 4)); 114 tmp = p1[12]; 115 tmp2 = (cur_word >> 24) & 0xFF; 116 sad = SUB_SAD(sad, tmp, tmp2); 117 tmp = p1[8]; 118 tmp2 = (cur_word >> 16) & 0xFF; 119 sad = SUB_SAD(sad, tmp, tmp2); 120 tmp = p1[4]; 121 tmp2 = (cur_word >> 8) & 0xFF; 122 sad = SUB_SAD(sad, tmp, tmp2); 123 tmp = p1[0]; 124 p1 += lx4; 125 tmp2 = (cur_word & 0xFF); 126 sad = SUB_SAD(sad, tmp, tmp2); 127 128 cur_word = *((uint32*)(blk += 4)); 129 tmp = p1[12]; 130 tmp2 = (cur_word >> 24) & 0xFF; 131 sad = SUB_SAD(sad, tmp, tmp2); 132 tmp = p1[8]; 133 tmp2 = (cur_word >> 16) & 0xFF; 134 sad = SUB_SAD(sad, tmp, tmp2); 135 tmp = p1[4]; 136 tmp2 = (cur_word >> 8) & 0xFF; 137 sad = SUB_SAD(sad, tmp, tmp2); 138 tmp = p1[0]; 139 p1 += lx4; 140 tmp2 = (cur_word & 0xFF); 141 sad = SUB_SAD(sad, tmp, tmp2); 142 143 cur_word = *((uint32*)(blk += 4)); 144 tmp = p1[12]; 145 tmp2 = (cur_word >> 24) & 0xFF; 146 sad = SUB_SAD(sad, tmp, tmp2); 147 tmp = p1[8]; 148 tmp2 = (cur_word >> 16) & 0xFF; 149 sad = SUB_SAD(sad, tmp, tmp2); 150 tmp = p1[4]; 151 tmp2 = (cur_word >> 8) & 0xFF; 152 sad = SUB_SAD(sad, tmp, tmp2); 153 tmp = p1[0]; 154 p1 += lx4; 155 tmp2 = (cur_word & 0xFF); 156 sad = SUB_SAD(sad, tmp, tmp2); 157 158 cur_word = *((uint32*)(blk += 4)); 159 tmp = p1[12]; 160 tmp2 = (cur_word >> 24) & 0xFF; 161 sad = SUB_SAD(sad, tmp, tmp2); 162 tmp = p1[8]; 163 tmp2 = (cur_word >> 16) & 0xFF; 164 sad = SUB_SAD(sad, tmp, tmp2); 165 tmp = p1[4]; 166 tmp2 = (cur_word >> 8) & 0xFF; 167 sad = SUB_SAD(sad, tmp, tmp2); 168 tmp = p1[0]; 169 p1 += lx4; 170 tmp2 = (cur_word & 0xFF); 171 sad = SUB_SAD(sad, tmp, tmp2); 172 173 NUM_SAD_MB(); 174 175 saddata[i] = sad; 176 177 if (i > 0) 178 { 179 if ((uint32)sad > ((uint32)dmin_lx >> 16)) 180 { 181 difmad = saddata[0] - ((saddata[1] + 1) >> 1); 182 (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); 183 (*countbreak)++; 184 return sad; 185 } 186 } 187 } 188 189 difmad = saddata[0] - ((saddata[1] + 1) >> 1); 190 (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); 191 (*countbreak)++; 192 return sad; 193 } 194 195 int AVCSAD_MB_HTFM(uint8 *ref, uint8 *blk, int dmin_lx, void *extra_info) 196 { 197 int sad = 0; 198 uint8 *p1; 199 200 int i; 201 int tmp, tmp2; 202 int lx4 = (dmin_lx << 2) & 0x3FFFC; 203 int sadstar = 0, madstar; 204 int *nrmlz_th = (int*) extra_info; 205 int *offsetRef = (int*) extra_info + 32; 206 uint32 cur_word; 207 208 madstar = (uint32)dmin_lx >> 20; 209 210 NUM_SAD_MB_CALL(); 211 212 blk -= 4; 213 for (i = 0; i < 16; i++) 214 { 215 p1 = ref + offsetRef[i]; 216 cur_word = *((uint32*)(blk += 4)); 217 tmp = p1[12]; 218 tmp2 = (cur_word >> 24) & 0xFF; 219 sad = SUB_SAD(sad, tmp, tmp2); 220 tmp = p1[8]; 221 tmp2 = (cur_word >> 16) & 0xFF; 222 sad = SUB_SAD(sad, tmp, tmp2); 223 tmp = p1[4]; 224 tmp2 = (cur_word >> 8) & 0xFF; 225 sad = SUB_SAD(sad, tmp, tmp2); 226 tmp = p1[0]; 227 p1 += lx4; 228 tmp2 = (cur_word & 0xFF); 229 sad = SUB_SAD(sad, tmp, tmp2); 230 231 cur_word = *((uint32*)(blk += 4)); 232 tmp = p1[12]; 233 tmp2 = (cur_word >> 24) & 0xFF; 234 sad = SUB_SAD(sad, tmp, tmp2); 235 tmp = p1[8]; 236 tmp2 = (cur_word >> 16) & 0xFF; 237 sad = SUB_SAD(sad, tmp, tmp2); 238 tmp = p1[4]; 239 tmp2 = (cur_word >> 8) & 0xFF; 240 sad = SUB_SAD(sad, tmp, tmp2); 241 tmp = p1[0]; 242 p1 += lx4; 243 tmp2 = (cur_word & 0xFF); 244 sad = SUB_SAD(sad, tmp, tmp2); 245 246 cur_word = *((uint32*)(blk += 4)); 247 tmp = p1[12]; 248 tmp2 = (cur_word >> 24) & 0xFF; 249 sad = SUB_SAD(sad, tmp, tmp2); 250 tmp = p1[8]; 251 tmp2 = (cur_word >> 16) & 0xFF; 252 sad = SUB_SAD(sad, tmp, tmp2); 253 tmp = p1[4]; 254 tmp2 = (cur_word >> 8) & 0xFF; 255 sad = SUB_SAD(sad, tmp, tmp2); 256 tmp = p1[0]; 257 p1 += lx4; 258 tmp2 = (cur_word & 0xFF); 259 sad = SUB_SAD(sad, tmp, tmp2); 260 261 cur_word = *((uint32*)(blk += 4)); 262 tmp = p1[12]; 263 tmp2 = (cur_word >> 24) & 0xFF; 264 sad = SUB_SAD(sad, tmp, tmp2); 265 tmp = p1[8]; 266 tmp2 = (cur_word >> 16) & 0xFF; 267 sad = SUB_SAD(sad, tmp, tmp2); 268 tmp = p1[4]; 269 tmp2 = (cur_word >> 8) & 0xFF; 270 sad = SUB_SAD(sad, tmp, tmp2); 271 tmp = p1[0]; 272 p1 += lx4; 273 tmp2 = (cur_word & 0xFF); 274 sad = SUB_SAD(sad, tmp, tmp2); 275 276 NUM_SAD_MB(); 277 278 sadstar += madstar; 279 if (((uint32)sad <= ((uint32)dmin_lx >> 16)) && (sad <= (sadstar - *nrmlz_th++))) 280 ; 281 else 282 return 65536; 283 } 284 285 return sad; 286 } 287 #endif /* HTFM */ 288 289 290 291