[XviD-devel] dynamic hpel/qpel decision

skal xvid-devel@xvid.org
03 Dec 2002 16:59:16 +0100


--=-r8DQfF+2SLxRefGAfLBN
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

	Hi Radek,

On Tue, 2002-12-03 at 10:41, skal wrote:
> 	Hi Radek and all,
> 
> On Mon, 2002-12-02 at 12:10, Radek Czyz wrote:
> 
> > PS does someone feel like writing an asm-ed Sobel edge detection? It's
> > not slow the way it is (copied from RefDivX's adaptive quantization
> > code) but can always be faster.
> 
> 	I got something like this burried in my comp-vision
> 	stuff. I'll try to dig it out. If I remember well,
> 	my filter was computing x-gradient, y-gradient and
> 	gradient squared norm in one shot, at reduced resolution.
> 	It was for edge thinning stuff 

	I've got some C-code here, for basic filtering.
	The corresponding MMX version has a little bug I
	need to find time to fix. Just try this one out,
	if it fits your needs...

	later,
			Skal



--=-r8DQfF+2SLxRefGAfLBN
Content-Disposition: attachment; filename=filter.c
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-c; name=filter.c; charset=ISO-8859-1

/**************************************************************************=
***
 *
 *  XVID MPEG-4 VIDEO CODEC
 *   4x4 filtering utilities
 *
 *  Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
 *
 *  This file is part of XviD, a free MPEG-4 video encoder/decoder
 *
 *  XviD is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 US=
A
 *
 *  Under section 8 of the GNU General Public License, the copyright
 *  holders of XVID explicitly forbid distribution in the following
 *  countries:
 *
 *    - Japan
 *    - United States of America
 *
 *  Linking XviD statically or dynamically with other modules is making a
 *  combined work based on XviD.  Thus, the terms and conditions of the
 *  GNU General Public License cover the whole combination.
 *
 *  As a special exception, the copyright holders of XviD give you
 *  permission to link XviD with independent modules that communicate with
 *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
 *  license terms of these independent modules, and to copy and distribute
 *  the resulting combined work under terms of your choice, provided that
 *  every copy of the combined work is accompanied by a complete copy of
 *  the source code of XviD (the version of XviD used to produce the
 *  combined work), being distributed under the terms of the GNU General
 *  Public License plus this exception.  An independent module is a module
 *  which is not derived from or based on XviD.
 *
 *  Note that people who make modified versions of XviD are not obligated
 *  to grant this special exception for their modified versions; it is
 *  their choice whether to do so.  The GNU General Public License gives
 *  permission to release a modified version without this exception; this
 *  exception also makes it possible to release a modified version which
 *  carries forward this exception.
 *
 * $Id: filter.c,v 1.11 2002/11/17 00:32:06 edgomez Exp $
 *
 **************************************************************************=
**/

  /* prototypes */

#include <stdint.h>

extern void xvid_Gradx_18x18_To_8x8_C(int8_t *Dst, int Dst_BpS,
                                      const uint8_t *Src, int Src_BpS);
extern void xvid_Grady_18x18_To_8x8_C(int8_t *Dst, int Dst_BpS,
                                      const uint8_t *Src, int Src_BpS);
extern void xvid_Grad2_18x18_To_8x8_C(uint8_t *Dst, int Dst_BpS,
                                      const uint8_t *Src, int Src_BpS);
extern void xvid_Smooth_18x18_To_8x8_C(uint8_t *Dst, int Dst_BpS,
                                       const uint8_t *Src, int Src_BpS);


/*////////////////////////////////////////////////////////
// Downsampling 4x4 filters:
//
//        [1 3 3 1]      [-1 -3  3  1]     [-1 -3 -3 -1]
// Smooth:[3 9 9 3]   Gx:[-3 -9  9  3]  Gy:[-3 -9 -9 -3]
//        [3 9 9 3]      [-3 -9  9  3]     [ 3  9  9  3]
//        [1 3 3 1]      [-1 -3  3  1]     [ 1  3  3  1]
//
//  Input:18x18   Output:8x8
//////////////////////////////////////////////////////////*/

void xvid_Gradx_18x18_To_8x8_C(int8_t *Dst, int Dst_BpS,
                               const uint8_t *Src, int Src_BpS)
{
#define LOAD(x) (x) =3D   3*(s[1]-s[0]) +s[2]-s[-1]; s +=3D Src_BpS

  int mx0, mx1, mx2, mx3;
  int i, j;

  for(i=3D0; i<8; ++i) {
    const uint8_t *s =3D Src - Src_BpS + 2*i;
    int8_t *d =3D Dst + i;

    LOAD(mx0);
    LOAD(mx1);

    for(j=3D0; j<4; ++j) {
      LOAD(mx2); mx1 +=3D mx2;
      LOAD(mx3); mx0 +=3D mx3;
      mx0 +=3D 3*mx1;
      *d =3D (32+mx0)>>7; d +=3D Dst_BpS;

      LOAD(mx0); mx3 +=3D mx0;
      LOAD(mx1); mx2 +=3D mx1;
      mx2 +=3D 3*mx3;
      *d =3D (32+mx2)>>7; d +=3D Dst_BpS;
    }
  }
#undef LOAD
}


void xvid_Grady_18x18_To_8x8_C(int8_t *Dst, int Dst_BpS,
                               const uint8_t *Src, int Src_BpS)
{
#define LOAD(x) (x) =3D 3*(s[1]+s[0]) +s[2]+s[-1]; s +=3D Src_BpS
  int mx0, mx1, mx2, mx3;
  int i, j;

  for(i=3D0; i<8; ++i) {
    const uint8_t *s =3D Src - Src_BpS + 2*i;
    int8_t *d =3D Dst + i;

    LOAD(mx0);
    LOAD(mx1);

    for(j=3D0; j<4; ++j) {
      LOAD(mx2); mx1 -=3D mx2;
      LOAD(mx3); mx0 -=3D mx3;
      mx0 +=3D 3*mx1;
      *d =3D (32-mx0)>>7; d +=3D Dst_BpS;

      LOAD(mx0); mx3 -=3D mx0;
      LOAD(mx1); mx2 -=3D mx1;
      mx2 +=3D 3*mx3;
      *d =3D (32-mx2)>>7; d +=3D Dst_BpS;
    }
  }
#undef LOAD
}

void xvid_Grad2_18x18_To_8x8_C(uint8_t *Dst, int Dst_BpS,
                               const uint8_t *Src, int Src_BpS)
{
#define LOAD(x,y) (x) =3D s[-1] + 3*s[0]; (y) =3D 3*s[1] + s[2]; s +=3D Src=
_BpS

  int mx0, mx1, mx2, mx3, my0, my1, my2, my3;
  int i, j;

  for(i=3D0; i<8; ++i) {
    const uint8_t *s =3D Src - Src_BpS + 2*i;
    int8_t *d =3D (int8_t*)Dst + i;

    LOAD(mx0,my0);
    LOAD(mx1,my1);

    for(j=3D0; j<4; ++j) {
      LOAD(mx2,my2); mx1 -=3D my2; my1 -=3D mx2;
      LOAD(mx3,my3); mx0 -=3D my3; my0 -=3D mx3;
      mx0 +=3D 3*mx1; my0 +=3D 3*my1;
      /*
          at this point:=20
         Gx  =3D (32+mx0-my0)>>7
         Gy  =3D (32-mx0-my0)>>7
         G^2 =3D (mx*mx0 + my0*my0 + (1<<13))>>14=20
      */
      *d =3D ( mx0*mx0 + my0*my0 + (1<<13) ) >> 14; d +=3D Dst_BpS;

      LOAD(mx0,my0); mx3 -=3D my0; my3 -=3D mx0;
      LOAD(mx1,my1); mx2 -=3D my1; my2 -=3D mx1;
      mx2 +=3D 3*mx3; my2 +=3D 3*my3;
      *d =3D ( mx2*mx2 + my3*my3 + (1<<13) ) >> 14; d +=3D Dst_BpS;
    }
  }
#undef LOAD
}

void xvid_Smooth_18x18_To_8x8_C(uint8_t *Dst, int Dst_BpS,
                                const uint8_t *Src, int Src_BpS)
{
#define LOAD(x) (x) =3D 3*(s[1]+s[0]) +s[2]+s[-1]; s +=3D Src_BpS
  int mx0, mx1, mx2, mx3;
  int i, j;

  for(i=3D0; i<8; ++i) {
    const uint8_t *s =3D Src - Src_BpS + 2*i;
    uint8_t *d =3D Dst + i;

    LOAD(mx0);
    LOAD(mx1);

    for(j=3D0; j<4; ++j) {
      LOAD(mx2); mx1 +=3D mx2;
      LOAD(mx3); mx0 +=3D mx3;
      mx0 +=3D 3*mx1;
      *d =3D (32+mx0)>>6; d +=3D Dst_BpS;

      LOAD(mx0); mx3 +=3D mx0;
      LOAD(mx1); mx2 +=3D mx1;
      mx2 +=3D 3*mx3;
      *d =3D (32+mx2)>>6; d +=3D Dst_BpS;
    }
  }
#undef LOAD
}


--=-r8DQfF+2SLxRefGAfLBN--