| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #include "mp4def.h" |
| #include "mp4lib_int.h" |
| |
| #include "sad_inline.h" |
| |
| #define Cached_lx 176 |
| |
| #ifdef _SAD_STAT |
| ULong num_sad_MB = 0; |
| ULong num_sad_Blk = 0; |
| ULong num_sad_MB_call = 0; |
| ULong num_sad_Blk_call = 0; |
| |
| #define NUM_SAD_MB_CALL() num_sad_MB_call++ |
| #define NUM_SAD_MB() num_sad_MB++ |
| #define NUM_SAD_BLK_CALL() num_sad_Blk_call++ |
| #define NUM_SAD_BLK() num_sad_Blk++ |
| |
| #else |
| |
| #define NUM_SAD_MB_CALL() |
| #define NUM_SAD_MB() |
| #define NUM_SAD_BLK_CALL() |
| #define NUM_SAD_BLK() |
| |
| #endif |
| |
| |
| /* consist of |
| Int SAD_Macroblock_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) |
| Int SAD_MB_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) |
| Int SAD_MB_HTFM(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) |
| Int SAD_Block_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info) |
| Int SAD_Blk_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) |
| Int SAD_MB_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) |
| Int SAD_MB_PAD1(UChar *ref,UChar *cur,Int dmin,Int lx,Int *rep); |
| Int SAD_MB_PADDING_HTFM_Collect(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info) |
| Int SAD_MB_PADDING_HTFM(UChar *ref,UChar *cur,Int dmin,Int lx,void *vptr) |
| */ |
| |
| |
| #ifdef __cplusplus |
| extern "C" |
| { |
| #endif |
| |
| Int SAD_MB_PAD1(UChar *ref, UChar *cur, Int dmin, Int lx, Int *rep); |
| |
| |
| /*================================================================== |
| Function: SAD_Macroblock |
| Date: 09/07/2000 |
| Purpose: Compute SAD 16x16 between blk and ref. |
| To do: Uniform subsampling will be inserted later! |
| Hypothesis Testing Fast Matching to be used later! |
| Changes: |
| 11/7/00: implemented MMX |
| 1/24/01: implemented SSE |
| ==================================================================*/ |
| /********** C ************/ |
| Int SAD_Macroblock_C(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) |
| { |
| int32 x10; |
| Int dmin = (ULong)dmin_lx >> 16; |
| Int lx = dmin_lx & 0xFFFF; |
| |
| OSCL_UNUSED_ARG(extra_info); |
| |
| NUM_SAD_MB_CALL(); |
| |
| x10 = simd_sad_mb(ref, blk, dmin, lx); |
| |
| return x10; |
| } |
| |
| #ifdef HTFM /* HTFM with uniform subsampling implementation, 2/28/01 */ |
| /*=============================================================== |
| Function: SAD_MB_HTFM_Collect and SAD_MB_HTFM |
| Date: 3/2/1 |
| Purpose: Compute the SAD on a 16x16 block using |
| uniform subsampling and hypothesis testing fast matching |
| for early dropout. SAD_MB_HP_HTFM_Collect is to collect |
| the statistics to compute the thresholds to be used in |
| SAD_MB_HP_HTFM. |
| Input/Output: |
| Changes: |
| ===============================================================*/ |
| |
| Int SAD_MB_HTFM_Collect(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) |
| { |
| Int i; |
| Int sad = 0; |
| UChar *p1; |
| Int lx4 = (dmin_lx << 2) & 0x3FFFC; |
| ULong cur_word; |
| Int saddata[16], tmp, tmp2; /* used when collecting flag (global) is on */ |
| Int difmad; |
| HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info; |
| Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg); |
| UInt *countbreak = &(htfm_stat->countbreak); |
| Int *offsetRef = htfm_stat->offsetRef; |
| |
| NUM_SAD_MB_CALL(); |
| |
| blk -= 4; |
| for (i = 0; i < 16; i++) |
| { |
| p1 = ref + offsetRef[i]; |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| NUM_SAD_MB(); |
| |
| saddata[i] = sad; |
| |
| if (i > 0) |
| { |
| if ((ULong)sad > ((ULong)dmin_lx >> 16)) |
| { |
| difmad = saddata[0] - ((saddata[1] + 1) >> 1); |
| (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); |
| (*countbreak)++; |
| return sad; |
| } |
| } |
| } |
| |
| difmad = saddata[0] - ((saddata[1] + 1) >> 1); |
| (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad); |
| (*countbreak)++; |
| return sad; |
| } |
| |
| Int SAD_MB_HTFM(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info) |
| { |
| Int sad = 0; |
| UChar *p1; |
| |
| Int i; |
| Int tmp, tmp2; |
| Int lx4 = (dmin_lx << 2) & 0x3FFFC; |
| Int sadstar = 0, madstar; |
| Int *nrmlz_th = (Int*) extra_info; |
| Int *offsetRef = (Int*) extra_info + 32; |
| ULong cur_word; |
| |
| madstar = (ULong)dmin_lx >> 20; |
| |
| NUM_SAD_MB_CALL(); |
| |
| blk -= 4; |
| for (i = 0; i < 16; i++) |
| { |
| p1 = ref + offsetRef[i]; |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| cur_word = *((ULong*)(blk += 4)); |
| tmp = p1[12]; |
| tmp2 = (cur_word >> 24) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[8]; |
| tmp2 = (cur_word >> 16) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[4]; |
| tmp2 = (cur_word >> 8) & 0xFF; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = p1[0]; |
| p1 += lx4; |
| tmp2 = (cur_word & 0xFF); |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| NUM_SAD_MB(); |
| |
| sadstar += madstar; |
| if (((ULong)sad <= ((ULong)dmin_lx >> 16)) && (sad <= (sadstar - *nrmlz_th++))) |
| ; |
| else |
| return 65536; |
| } |
| |
| return sad; |
| } |
| #endif /* HTFM */ |
| |
| #ifndef NO_INTER4V |
| /*================================================================== |
| Function: SAD_Block |
| Date: 09/07/2000 |
| Purpose: Compute SAD 16x16 between blk and ref. |
| To do: Uniform subsampling will be inserted later! |
| Hypothesis Testing Fast Matching to be used later! |
| Changes: |
| 11/7/00: implemented MMX |
| 1/24/01: implemented SSE |
| ==================================================================*/ |
| /********** C ************/ |
| Int SAD_Block_C(UChar *ref, UChar *blk, Int dmin, Int lx, void *) |
| { |
| Int sad = 0; |
| |
| Int i; |
| UChar *ii; |
| Int *kk; |
| Int tmp, tmp2, tmp3, mask = 0xFF; |
| Int width = (lx - 32); |
| |
| NUM_SAD_BLK_CALL(); |
| |
| ii = ref; |
| kk = (Int*)blk; /* assuming word-align for blk */ |
| for (i = 0; i < 8; i++) |
| { |
| tmp3 = kk[1]; |
| tmp = ii[7]; |
| tmp2 = (UInt)tmp3 >> 24; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = ii[6]; |
| tmp2 = (tmp3 >> 16) & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = ii[5]; |
| tmp2 = (tmp3 >> 8) & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = ii[4]; |
| tmp2 = tmp3 & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp3 = *kk; |
| kk += (width >> 2); |
| tmp = ii[3]; |
| tmp2 = (UInt)tmp3 >> 24; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = ii[2]; |
| tmp2 = (tmp3 >> 16) & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = ii[1]; |
| tmp2 = (tmp3 >> 8) & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| tmp = *ii; |
| ii += lx; |
| tmp2 = tmp3 & mask; |
| sad = SUB_SAD(sad, tmp, tmp2); |
| |
| NUM_SAD_BLK(); |
| |
| if (sad > dmin) |
| return sad; |
| } |
| |
| return sad; |
| } |
| |
| #endif /* NO_INTER4V */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| |
| |