Windows2003-3790/enduser/netmeeting/av/codecs/dec/dech261/me2.c
2020-09-30 16:53:55 +02:00

984 lines
30 KiB
C

/* File: sv_h261_me2.c */
/*****************************************************************************
** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
** **
** All Rights Reserved. Unpublished rights reserved under the copyright **
** laws of the United States. **
** **
** The software contained on this media is proprietary to and embodies **
** the confidential technology of Digital Equipment Corporation. **
** Possession, use, duplication or dissemination of the software and **
** media is authorized only pursuant to a valid written license from **
** Digital Equipment Corporation. **
** **
** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
** Government is subject to restrictions as set forth in Subparagraph **
** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
******************************************************************************/
/*************************************************************
This file does much of the motion estimation and compensation.
*************************************************************/
/*
#define USE_C
#define _SLIBDEBUG_
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "sv_intrn.h"
#include "SC_err.h"
#include "sv_h261.h"
#include "proto.h"
#ifdef _SLIBDEBUG_
#define _DEBUG_ 0 /* detailed debuging statements */
#define _VERBOSE_ 0 /* show progress */
#define _VERIFY_ 1 /* verify correct operation */
#define _WARN_ 0 /* warnings about strange behavior */
#endif
#define Abs(value) ( (value < 0) ? (-value) : value)
/*
#define MEBUFSIZE 1024
int MeVAR[MEBUFSIZE];
int MeVAROR[MEBUFSIZE];
int MeMWOR[MEBUFSIZE];
int MeX[MEBUFSIZE];
int MeY[MEBUFSIZE];
int MeVal[MEBUFSIZE];
int MeOVal[MEBUFSIZE];
int PreviousMeOVal[MEBUFSIZE];
*/
/*
** Function: CrawlMotionEstimation()
** Purpose: Does motion estimation on all aligned
** 16x16 blocks in two memory structures.
*/
void CrawlMotionEstimation(SvH261Info_t *H261, unsigned char *pm,
unsigned char *rm, unsigned char *cm)
{
const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold;
const int height=H261->YHeight, width=H261->YWidth;
const int ylimit=height-16, xlimit=width-16;
unsigned char *pptr, *cptr;
register int x, y, xd, yd;
int MeN, MV;
int i, j, val;
int VAROR, MWOR;
unsigned char *cptr2;
_SlibDebug(_VERBOSE_,
printf("CrawlMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
H261, pm, rm, cm) );
for(MeN=0, y=0; y<height; y+=16)
{
cptr=cm + (y * width);
pptr=rm + (y * width);
_SlibDebug(_VERIFY_ && ((int)cptr)%8,
printf("FastBME() cm Not quad word aligned\n") );
for(x=0; x<width; x+=16, MeN++,cptr+=16,pptr+=16)
{
xd=yd=0;
#ifdef USE_C
MV = blockdiff16_C(cptr, pptr, width,400000);
#else
MV = blockdiff16(cptr, pptr, width,400000);
#endif
_SlibDebug(_DEBUG_, printf("First MV=%d\n",MV) );
H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
H261->MeOVal[MeN] = MV;
if (MV >= Threshold)
{
int d=0, MVnew, bestxd, bestyd, lastxd, lastyd;
#ifdef USE_C
#define bd(nxd, nyd) {MVnew=blockdiff16_C(cptr, pptr+nxd+(nyd*width), width, MV); \
if (MVnew<MV) {bestxd=nxd; bestyd=nyd; MV=MVnew;} \
_SlibDebug(_DEBUG_, printf("MVnew=%d x=%d y=%d\n",MVnew,nxd,nyd) );}
#else
#define bd(nxd, nyd) {MVnew=blockdiff16(cptr, pptr+nxd+(nyd*width), width, MV); \
if (MVnew<MV) {bestxd=nxd; bestyd=nyd; MV=MVnew;} \
_SlibDebug(_DEBUG_, printf("MVnew=%d x=%d y=%d\n",MVnew,nxd,nyd) );}
#endif
lastxd=0;
lastyd=0;
while (MV >= Threshold &&
xd>-SearchLimit && xd<SearchLimit &&
yd>-SearchLimit && yd<SearchLimit)
{
bestxd=xd;
bestyd=yd;
_SlibDebug(_DEBUG_, printf("xd=%d yd=%d d=%d MV=%d\n",xd, yd, d, MV));
switch (d) /* d is a vector for movement */
{
case -4: /* moved down & right */
if (x+xd<xlimit)
{
bd(xd+1, yd-1);
bd(xd+1, yd);
if (y+yd<ylimit)
{
bd(xd+1, yd+1);
bd(xd, yd+1);
bd(xd-1, yd+1);
}
}
else if (y+yd<ylimit)
{
bd(xd, yd+1);
bd(xd-1, yd+1);
}
break;
case -3: /* moved down */
if (y+yd>0)
{
bd(xd-1, yd-1);
bd(xd, yd-1);
bd(xd+1, yd-1);
}
break;
case -2: /* moved up & right */
if (x+xd<xlimit)
{
bd(xd+1, yd+1);
bd(xd+1, yd);
if (y+yd>0)
{
bd(xd+1, yd-1);
bd(xd, yd-1);
bd(xd-1, yd-1);
}
}
else if (y+yd>0)
{
bd(xd, yd-1);
bd(xd-1, yd-1);
}
break;
case -1: /* moved left */
if (x+xd>0)
{
if (y+yd > 0)
bd(xd-1, yd-1);
bd(xd-1, yd);
bd(xd-1, yd+1);
}
break;
case 0: /* no movement */
if (x+xd<=0) /* at left edge */
{
if (y+yd<=0) /* at top-left corner */
{
bd(xd+1, yd);
bd(xd+1, yd+1);
bd(xd, yd+1);
}
else if (y+yd>=ylimit) /* at bottom-left corner */
{
bd(xd+1, yd);
bd(xd+1, yd-1);
bd(xd, yd-1);
}
else /* at left edge, y within limits */
{
bd(xd, yd+1);
bd(xd, yd-1);
bd(xd+1, yd-1);
bd(xd+1, yd);
bd(xd+1, yd+1);
}
}
else if (x+xd>=xlimit) /* at right edge */
{
if (y+yd<=0) /* at top-right corner */
{
bd(xd-1, yd);
bd(xd-1, yd+1);
bd(xd, yd+1);
}
else if (y+yd>=ylimit) /* at bottom-right corner */
{
bd(xd-1, yd);
bd(xd-1, yd-1);
bd(xd, yd-1);
}
else /* at right edge, y within limits */
{
bd(xd, yd+1);
bd(xd, yd-1);
bd(xd-1, yd-1);
bd(xd-1, yd);
bd(xd-1, yd+1);
}
}
else if (y+yd<=0) /* at top edge, x within limits */
{
bd(xd-1, yd);
bd(xd+1, yd);
bd(xd-1, yd+1);
bd(xd, yd+1);
bd(xd+1, yd+1);
}
else if (y+yd>=ylimit) /* at bottom edge, x within limits */
{
bd(xd-1, yd);
bd(xd+1, yd);
bd(xd-1, yd-1);
bd(xd, yd-1);
bd(xd+1, yd-1);
}
else /* within all limits */
{
bd(xd-1, yd);
bd(xd+1, yd);
bd(xd-1, yd-1);
bd(xd-1, yd+1);
bd(xd+1, yd-1);
bd(xd+1, yd+1);
bd(xd, yd-1);
bd(xd, yd+1);
}
break;
case 1: /* moved right */
if (x+xd<xlimit)
{
if (y+yd > 0)
bd(xd+1, yd-1);
bd(xd+1, yd);
bd(xd+1, yd+1);
}
break;
case 2: /* moved down & left */
if (x+xd>0)
{
if (y+yd > 0)
bd(xd-1, yd-1);
bd(xd-1, yd);
if (y+yd<ylimit)
{
bd(xd-1, yd+1);
bd(xd, yd+1);
bd(xd+1, yd+1);
}
}
else if (y+yd<ylimit)
{
bd(xd, yd+1);
bd(xd+1, yd+1);
}
break;
case 3: /* moved down */
if (y+yd<ylimit)
{
bd(xd-1, yd+1);
bd(xd, yd+1);
bd(xd+1, yd+1);
}
break;
case 4: /* moved down & right */
if (x+xd>0)
{
bd(xd-1, yd);
bd(xd-1, yd+1);
if (y+yd>0)
{
bd(xd-1, yd-1);
bd(xd, yd-1);
bd(xd+1, yd-1);
}
}
else if (y+yd>0)
{
bd(xd, yd-1);
bd(xd+1, yd-1);
}
break;
default:
_SlibDebug(_VERIFY_,
printf("Illegal movement: d = %d\n", d) );
}
if (bestxd==xd && bestyd==yd) /* found closest motion vector */
break;
lastxd=xd;
lastyd=yd;
xd=bestxd;
yd=bestyd;
d = (xd-lastxd) + 3*(yd-lastyd); /* calculate the movement */
}
}
H261->MeX[MeN] = xd;
H261->MeY[MeN] = yd;
H261->MeVal[MeN] = MV;
H261->MeVAR[MeN] = MV;
_SlibDebug(_DEBUG_ && (xd || yd),
printf("New MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
MeN, x, y, xd, yd, MV) );
#if 1
for(cptr2 = cptr, MWOR=0, i=0; i<16; i++)
{
for(j=0; j<16; j++)
MWOR += *cptr2++;
cptr2 += width-16;
}
MWOR /= 256;
H261->MeMWOR[MeN] = MWOR;
for(cptr2 = cptr, VAROR=0, i=0; i<16; i++)
{
for (j=0; j<16; j++)
{
val=*cptr2++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
}
cptr2 += width-16;
}
H261->MeVAROR[MeN] = VAROR;
_SlibDebug(_DEBUG_,
printf("x=%d y=%d MV=%d MWOR=%d VAROR=%d\n", x, y, MV, MWOR, VAROR) );
#if 0
for(cptr2 = cptr, MWOR=0, i=0; i<16; i++)
{
for(j=0; j<16; j++)
MWOR += *cptr2++;
cptr2 += width-16;
}
MWOR /= 256;
H261->MeMWOR[MeN] = MV/10; /* MWOR; */
for(cptr2 = cptr, VAROR=0, i=0; i<16; i++)
{
for (j=0; j<16; j++)
{
val=*cptr2++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
}
cptr2 += width-16;
}
H261->MeVAROR[MeN] = MV; /* VAROR; */
_SlibDebug(_DEBUG_,
printf("x=%d y=%d MV=%d MWOR=%d VAROR=%d\n", x, y, MV, MWOR, VAROR) );
#endif
#else
H261->MeMWOR[MeN] = 0;
H261->MeVAROR[MeN] = 0;
#endif
}
}
_SlibDebug(_DEBUG_, printf("CrawlMotionEstimation() Out\n") );
}
/*
** Function: BruteMotionEstimation()
** Purpose: Does a brute-force motion estimation on all aligned
** 16x16 blocks in two memory structures.
*/
void BruteMotionEstimation(SvH261Info_t *H261, unsigned char *rm,
unsigned char *rrm, unsigned char *cm)
{
const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold/8;
const int YHeight=H261->YHeight, YWidth=H261->YWidth;
const int YHeight16=YHeight-16, YWidth16=YWidth-16;
unsigned char *bptr, *cptr, *baseptr;
register int MeN, i, j, x, y, px, py;
int MX, MY, MV, val;
int VAR, VAROR, MWOR;
const int jump = YWidth;
unsigned char data;
_SlibDebug(_VERBOSE_,
printf("BruteMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
H261, rm, rrm, cm) );
_SlibDebug(_VERIFY_ && ((int)cm)%8,
printf("FastBME() cm Not quad aligned\n") );
for(MeN=0, y=0; y<YHeight; y+=16)
{
baseptr=cm + (y * YWidth);
for(x=0; x<YWidth; x+=16, MeN++,baseptr+=16)
{
MX=MY=0;
bptr = rrm + x + (y * YWidth);
#if 1
#ifdef USE_C
MV = fblockdiff16_C(baseptr, bptr, YWidth, 65536) / 4;
#else
MV = blockdiff16(baseptr, bptr, YWidth, 65536) / 4;
#endif
#else
#ifdef USE_C
MV = fblockdiff16_sub_C(baseptr, bptr, jump);
#else
MV = fblockdiff16_sub(baseptr, bptr, jump);
#endif
#endif
H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
H261->MeOVal[MeN] = MV*4;
_SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
if (MV >= Threshold)
{
int Xl, Xh, Yl, Yh;
/* MV = 362182; */
Xl = ((x-SearchLimit)/2)*2;
Xh = ((x+SearchLimit)/2)*2;
Yl = ((y-SearchLimit)/2)*2;
Yh = ((y+SearchLimit)/2)*2;
if (Xl < 0) Xl = 0;
if (Xh > YWidth16) Xh = YWidth16;
if (Yl < 0) Yl = 0;
if (Yh > YHeight16) Yh = YHeight16;
for (px=Xl; px<=Xh && MV >= Threshold; px +=2)
{
bptr = rrm + px + (Yl * YWidth);
for (py=Yl; py<=Yh && MV >= Threshold; py += 2, bptr+=YWidth*2)
{
_SlibDebug(_DEBUG_, printf("blockdiff16_sub(%p, %p, %d, %d)\n",
baseptr,bptr,YWidth,MV) );
#ifdef USE_C
val = blockdiff16_sub_C(baseptr, bptr, jump, MV);
#else
val = blockdiff16_sub(baseptr, bptr, jump, MV);
#endif
_SlibDebug(_DEBUG_, printf("blockdiff16_sub() Out val=%d\n", val) );
if (val < MV)
{
MV = val;
MX = px - x;
MY = py - y;
}
}
}
px = MX + x;
py = MY + y;
MV = 65536;
Xl = px - 1;
Xh = px + 1;
Yl = py - 1;
Yh = py + 1;
if (Xl < 0) Xl = 0;
if (Xh > YWidth16) Xh = YWidth16;
if (Yl < 0) Yl = 0;
if (Yh > YHeight16) Yh = YHeight16;
for (px=Xl; px<=Xh && MV>=Threshold; px++)
{
bptr = rrm + px + (Yl * YWidth);
for (py=Yl; py<=Yh && MV>=Threshold; py++, bptr+=YWidth)
{
#ifdef USE_C
val = blockdiff16_C(baseptr, bptr, YWidth, MV);
#else
val = blockdiff16(baseptr, bptr, YWidth, MV);
#endif
if (val < MV)
{
MV = val;
MX = px - x;
MY = py - y;
}
}
}
}
_SlibDebug(_DEBUG_, printf("MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
MeN, x, y, MX, MY, MV) );
H261->MeX[MeN] = MX;
H261->MeY[MeN] = MY;
H261->MeVal[MeN] = MV;
bptr = rrm + MX + x + ((MY+y) * YWidth);
cptr = baseptr;
for(VAR=0, MWOR=0, i=0; i<16; i++)
{
for(j=0; j<16; j++)
{
MWOR += (data=*cptr++);
val = *bptr++ - data;
VAR += (val > 0) ? val : -val;
}
bptr += YWidth16;
cptr += YWidth16;
}
H261->MeVAR[MeN] = VAR;
MWOR /= 256;
H261->MeMWOR[MeN] = MWOR;
cptr = baseptr;
for(VAROR=0, i=0; i<16; i++)
{
for (j=0; j<16; j++)
{
val=*cptr++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
}
cptr += YWidth16;
}
H261->MeVAROR[MeN] = VAROR;
}
}
_SlibDebug(_DEBUG_, printf("BruteMotionEstimation() Out\n") );
}
/*
* logarithmetic search block matching
*
* blk: top left pel of (16*h) block
* h: height of block
* lx: distance (in bytes) of vertically adjacent pels in ref,blk
* org: top left pel of source reference picture
* ref: top left pel of reconstructed reference picture
* i0,j0: center of search window
* sx,sy: half widths of search window
* xmax,ymax: right/bottom limits of search area
* iminp,jminp: pointers to where the result is stored
* result is given as half pel offset from ref(0,0)
* i.e. NOT relative to (i0,j0)
*/
void Logsearch(SvH261Info_t *H261, unsigned char *rm, unsigned char *rrm, unsigned char *cm)
{
const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold/8;
const int YHeight=H261->YHeight, YWidth=H261->YWidth;
const int YHeight16=YHeight-16, YWidth16=YWidth-16;
unsigned char *bptr, *cptr, *baseptr;
register int MeN, i, j, x, y, px, py;
int MX, MY, MV, val;
int VAR, VAROR, MWOR;
const int jump = YWidth;
unsigned char data;
int bsx,bsy,ijk;
int srched_loc[33][33] ;
struct five_loc{int x ; int y ;} ij[5] ;
_SlibDebug(_VERBOSE_,
printf("BruteMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
H261, rm, rrm, cm) );
_SlibDebug(_VERIFY_ && ((int)cm)%8,
printf("FastBME() cm Not quad aligned\n") );
for(MeN=0, y=0; y<YHeight; y+=16)
{
baseptr=cm + (y * YWidth);
for(x=0; x<YWidth; x+=16, MeN++,baseptr+=16)
{
MX=MY=0;
bptr = rrm + x + (y * YWidth);
#if 1
#ifdef USE_C
MV = blockdiff16_C(baseptr, bptr, YWidth, 65536) / 4;
#else
MV = blockdiff16(baseptr, bptr, YWidth, 65536) / 4;
#endif
#else
#ifdef USE_C
MV = fblockdiff16_sub_C(baseptr, bptr, jump);
#else
MV = fblockdiff16_sub(baseptr, bptr, jump);
#endif
#endif
H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
H261->MeOVal[MeN] = MV*4;
_SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
if (MV >= Threshold)
{
int Xl, Xh, Yl, Yh;
Xl = x-SearchLimit;
Xh = x+SearchLimit;
Yl = y-SearchLimit;
Yh = y+SearchLimit;
if (Xl < 0) Xl = 0;
if (Xh > YWidth16) Xh = YWidth16;
if (Yl < 0) Yl = 0;
if (Yh > YHeight16) Yh = YHeight16;
/* x-y step size */
if(SearchLimit > 8) bsx = bsy = 8 ;
else if(SearchLimit > 4) bsx = bsy = 4 ;
else bsx = bsy = 2 ;
/* initialized searched locations */
for(i=0;i<33;i++)
for(j=0;j<33;j++) srched_loc[i][j] = 0 ;
/* The center of the seach window */
i = x;
j = y;
/* reduce window size by half until the window is 3x3 */
for(;bsx > 1;bsx /= 2, bsy /= 2){
/* five searched locations for each step */
ij[0].x = i ; ij[0].y = j ;
ij[1].x = i - bsx ; ij[1].y = j ;
ij[2].x = i + bsx ; ij[2].y = j ;
ij[3].x = i ; ij[3].y = j - bsy;
ij[4].x = i ; ij[4].y = j + bsy;
/* search */
for(ijk = 0; ijk < 5; ijk++) {
if(ij[ijk].x>=Xl && ij[ijk].x<=Xh &&
ij[ijk].y>=Yl && ij[ijk].y<=Yh &&
srched_loc[ij[ijk].x - x + 16][ij[ijk].y - y + 16] == 0)
{
#ifdef USE_C
val = fblockdiff16_sub_C(baseptr, rrm +ij[ijk].x+ij[ijk].y*YWidth, jump);
#else
val = fblockdiff16_sub(baseptr, rrm +ij[ijk].x+ij[ijk].y*YWidth, jump);
#endif
srched_loc[ij[ijk].x - x + 16][ij[ijk].y - y + 16] = 1 ;
if(val<MV)
{
MV = val ;
MX = ij[ijk].x - x;
MY = ij[ijk].y - y;
}
}
}
/* if the best point was found, stop the search */
if(MV == 0 ) break ;
else { /* else, go to next step */
i = MX + x;
j = MY + y;
}
}
px = MX + x;
py = MY + y;
MV = 65536;
Xl = px - 1;
Xh = px + 1;
Yl = py -1;
Yh = py + 1;
if (Xl < 0) Xl = 0;
if (Xh > YWidth16) Xh = YWidth16;
if (Yl < 0) Yl = 0;
if (Yh > YHeight16) Yh = YHeight16;
for (px=Xl; px<=Xh && MV>=Threshold; px++)
{
bptr = rrm + px + (Yl * YWidth);
for (py=Yl; py<=Yh && MV>=Threshold; py++, bptr+=YWidth)
{
#ifdef USE_C
val = blockdiff16_C(baseptr, bptr, YWidth, MV);
#else
val = blockdiff16(baseptr, bptr, YWidth, MV);
#endif
if (val < MV)
{
MV = val;
MX = px - x;
MY = py - y;
}
}
}
}
_SlibDebug(_DEBUG_, printf("MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
MeN, x, y, MX, MY, MV) );
H261->MeX[MeN] = MX;
H261->MeY[MeN] = MY;
H261->MeVal[MeN] = MV;
bptr = rrm + MX + x + ((MY+y) * YWidth);
cptr = baseptr;
for(VAR=0, MWOR=0, i=0; i<16; i++)
{
for(j=0; j<16; j++)
{
MWOR += (data=*cptr++);
val = *bptr++ - data;
VAR += (val > 0) ? val : -val;
}
bptr += YWidth16;
cptr += YWidth16;
}
H261->MeVAR[MeN] = VAR;
MWOR /= 256;
H261->MeMWOR[MeN] = MWOR;
cptr = baseptr;
for(VAROR=0, i=0; i<16; i++)
{
for (j=0; j<16; j++)
{
val=*cptr++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
}
cptr += YWidth16;
}
H261->MeVAROR[MeN] = VAROR;
}
}
_SlibDebug(_DEBUG_, printf("BruteMotionEstimation() Out\n") );
}
#if 0
/*************** This is the original BME *********************/
/*
** Function: FastBME()
** Purpose: Does a fast brute-force motion estimation with two indexes
** into two memory structures. The motion estimation has a
** short-circuit abort to speed up calculation.
*/
void FastBME(SvH261Info_t *H261, int rx, int ry,
unsigned char *rm, unsigned char *rrm,
int cx, int cy, unsigned char *cm, int MeN)
{
int px,py;
int MX, MY, MV, OMV;
int Xl, Xh, Yl, Yh;
int VAR, VAROR, MWOR;
int i,j,data,val;
unsigned char *bptr,*cptr;
unsigned char *baseptr;
int count = 0;
const int jump = 2*H261->YWidth;
_SlibDebug(_DEBUG_, printf("FastBME(H261=0x%p) YWidth=%d YHeight=%d\n",
H261,H261->YWidth,H261->YHeight) );
MX=MY=MV=0;
bptr=rm + rx + (ry * H261->YWidth);
baseptr=cm + cx + (cy * H261->YWidth);
_SlibDebug(_VERIFY_ && ((int)baseptr)%8,
printf(((int)baseptr)%8, "FastBME() baseptr Not quad aligned\n") );
cptr=baseptr;
#ifdef USE_C
MV = fblockdiff16_sub_C(baseptr, bptr, H261->YWidth);
#else
MV = fblockdiff16_sub(baseptr, bptr, jump);
#endif
OMV=MV*4;
_SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
cptr = baseptr;
px=rx;
py=ry;
if(OMV > H261->MotionThreshold)
{
MV = 362182;
Xl = ((rx-H261->SearchLimit)/2)*2;
Xh = ((rx+H261->SearchLimit)/2)*2;
Yl = ((ry-H261->SearchLimit)/2)*2;
Yh = ((ry+H261->SearchLimit)/2)*2;
Xl = (Xl < 0) ? 0 : Xl;
Xh = (Xh > H261->YWidth-16) ? (H261->YWidth-16) : Xh;
Yl = (Yl < 0) ? 0 : Yl;
Yh = (Yh > H261->YHeight-16) ? (H261->YHeight-16) : Yh;
for(px=Xl; px <=Xh ; px += 2) {
for(py=Yl; py <=Yh; py += 2) {
bptr = rm + px + (py * H261->YWidth);
_SlibDebug(_DEBUG_, printf("blockdiff16_sub(%p, %p, %d, %d)\n",
baseptr,bptr,H261->YWidth,MV) );
#ifdef USE_C
val = blockdiff16_sub_C(baseptr, bptr, H261->YWidth);
#else
val = blockdiff16_sub(baseptr, bptr, jump, MV);
#endif
_SlibDebug(_DEBUG_, printf("blockdiff16_sub() Out val=%d\n",val));
if (val < MV)
{
MV = val;
MX = px - rx;
MY = py - ry;
}
}
}
px = MX + rx;
py = MY + ry;
bptr = rrm + px +(py*H261->YWidth);
MV = 232141;
Xl = px -1;
Xh = px +1;
Yl = py -1;
Yh = py +1;
Xl = (Xl < 0) ? 0 : Xl;
Xh = (Xh > (H261->YWidth-16)) ? (H261->YWidth-16) : Xh;
Yl = (Yl < 0) ? 0 : Yl;
Yh = (Yh > (H261->YHeight-16)) ? (H261->YHeight-16) : Yh;
count = 0;
for(px=Xl;px<=Xh;px++) {
for(py=Yl;py<=Yh;py++) {
bptr = rrm + px + (py * H261->YWidth);
#ifdef USE_C
val = blockdiff16_C(baseptr, bptr, H261->YWidth);
#else
val = blockdiff16(baseptr, bptr, H261->YWidth,MV);
#endif
if (val < MV)
{
MV = val;
MX = px - rx;
MY = py - ry;
}
}
}
}
bptr = rm + (MX+rx) + ((MY+ry) * H261->YWidth);
cptr = baseptr;
for(VAR=0,MWOR=0,i=0;i<16;i++)
{
for(j=0;j<16;j++)
{
data = *bptr - *cptr;
VAR += Abs(data);
MWOR += *cptr;
bptr++;
cptr++;
}
bptr += (H261->YWidth - 16);
cptr += (H261->YWidth - 16);
}
MWOR = MWOR/256;
VAR = VAR;
cptr = baseptr;
for(VAROR=0,i=0;i<16;i++)
{
for(j=0;j<16;j++)
{
VAROR += Abs(*cptr-MWOR);
cptr++;
}
cptr += (H261->YWidth - 16);
}
/* VAROR = VAROR; */
_SlibDebug(_DEBUG_, printf("\n Pos %d MX %d MY %d", MeN, MX, MY) );
H261->MeVAR[MeN] = VAR;
H261->MeVAROR[MeN] = VAROR;
H261->MeMWOR[MeN] = MWOR;
H261->MeX[MeN] = MX;
H261->MeY[MeN] = MY;
H261->MeVal[MeN] = MV;
H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
H261->MeOVal[MeN] = OMV;
_SlibDebug(_DEBUG_, printf("FastBME() Out\n") );
}
/*
** Function: BruteMotionEstimation2()
** Purpose: Does a brute-force motion estimation on all aligned
** 16x16 blocks in two memory structures.
*/
void BruteMotionEstimation2(SvH261Info_t *H261, unsigned char *pmem,
unsigned char *recmem, unsigned char *fmem)
{
BEGIN("BruteMotionEstimation2");
const int YHeight=H261->YHeight, YWidth=H261->YWidth;
int x,y,MeN;
_SlibDebug(_DEBUG_, printf("BruteMotionEstimation(H261=0x%p,%p,%p,%p) In\n",
H261, pmem, recmem, fmem) );
for(MeN=0,y=0; y<YHeight; y+=16)
for(x=0; x<YWidth; x+=16, MeN++)
FastBME(H261,x,y,pmem,recmem, x,y,fmem,MeN);
_SlibDebug(_DEBUG_, printf("BruteMotionEstimation2() Out\n") );
}
#endif
int blockdiff16_C(unsigned char* ptr1, unsigned char *ptr2, int Jump, int mv)
{
int Sum=0, Pixel_diff, i, j, inc=Jump-16;
_SlibDebug(_DEBUG_,
printf("blockdiff16_C(ptr1=%p, ptr2=%p, Jump=%d, MV=%d)\n",
ptr1, ptr2, Jump, mv) );
for(j=0;j<16;j++) {
for(i=0;i<16;i++) {
Pixel_diff = (*ptr1++ - *ptr2++);
Sum += Abs(Pixel_diff);
}
_SlibDebug(_DEBUG_, printf ("Sum: %d MV: %d \n" , Sum, mv) );
if (Sum > mv)
break;
ptr1 += inc;
ptr2 += inc;
}
return(Sum);
}
int blockdiff16_sub_C(unsigned char* ptr1, unsigned char *ptr2,
int Jump, int mv)
{
int Sum=0, Pixel_diff, i,j,inc=2*Jump-16;
_SlibDebug(_DEBUG_,
printf("blockdiff16_sub_C(ptr1=%p, ptr2=%p, Jump=%d, MV=%d)\n",
ptr1, ptr2, Jump, mv) );
for(j=0; j<8; j++) {
for(i=0; i<8; i++) {
Pixel_diff = (*ptr1 - *ptr2);
ptr1 += 2;
ptr2 += 2;
Sum += Abs(Pixel_diff);
}
_SlibDebug(_DEBUG_, printf("Sum: %d MV: %d \n", Sum, mv) );
if (Sum > mv)
break;
ptr1 += inc;
ptr2 += inc;
}
_SlibDebug(_DEBUG_, printf("blockdiff16_sub_C() Out\n") );
return(Sum);
}
/*
** Function: fblockdiff16_sub_C
** Purpose: First blcok diff.
*/
int fblockdiff16_sub_C(unsigned char* ptr1, unsigned char *ptr2,
int Jump)
{
int Sum=0, Pixel_diff, i,j, inc=2*Jump-16;
_SlibDebug(_DEBUG_,
printf("fblockdiff16_sub_C(ptr1=%p, ptr2=%p, Jump=%d)\n",
ptr1, ptr2, Jump) );
for(j=0; j<8; j++) {
for(i=0; i<8; i++) {
Pixel_diff = (*ptr1 - *ptr2);
ptr1 += 2;
ptr2 += 2;
Sum += Abs(Pixel_diff);
}
ptr1 += inc;
ptr2 += inc;
}
return(Sum);
}