blob: 8d18f4588ed61a1cc21beac5d909df9c175c7048 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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