[Theora-dev] Re: MMX/mmxext optimisations
Adam D. Moss
adam at gimp.org
Tue Aug 24 03:42:45 PDT 2004
Lovely. I actually get up to about 4x speed improvement
on some encodes.
Here's a patch that is ported to SVN HEAD.
--Adam
-------------- next part --------------
Index: lib/reconstruct.c
===================================================================
--- lib/reconstruct.c (revision 7621)
+++ lib/reconstruct.c (working copy)
@@ -16,12 +16,28 @@
********************************************************************/
#include "encoder_internal.h"
+#include "dsp.h"
+#include "cpu.h"
-void ReconIntra( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- ogg_int16_t * ChangePtr, ogg_uint32_t LineStep ) {
+static void copy8x8__c (unsigned char *src,
+ unsigned char *dest,
+ unsigned int stride)
+{
+ int j;
+ for ( j = 0; j < 8; j++ ){
+ ((ogg_uint32_t*)dest)[0] = ((ogg_uint32_t*)src)[0];
+ ((ogg_uint32_t*)dest)[1] = ((ogg_uint32_t*)src)[1];
+ src+=stride;
+ dest+=stride;
+ }
+}
+
+static void recon_intra8x8__c (unsigned char *ReconPtr, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep)
+{
ogg_uint32_t i;
- for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++ ){
+ for (i = 8; i; i--){
/* Convert the data back to 8 bit unsigned */
/* Saturate the output to unsigend 8 bit values */
ReconPtr[0] = clamp255( ChangePtr[0] + 128 );
@@ -34,17 +50,16 @@
ReconPtr[7] = clamp255( ChangePtr[7] + 128 );
ReconPtr += LineStep;
- ChangePtr += BLOCK_HEIGHT_WIDTH;
+ ChangePtr += 8;
}
-
}
-void ReconInter( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- unsigned char * RefPtr, ogg_int16_t * ChangePtr,
- ogg_uint32_t LineStep ) {
+static void recon_inter8x8__c (unsigned char *ReconPtr, unsigned char *RefPtr,
+ ogg_int16_t *ChangePtr, ogg_uint32_t LineStep)
+{
ogg_uint32_t i;
- for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++) {
+ for (i = 8; i; i--){
ReconPtr[0] = clamp255(RefPtr[0] + ChangePtr[0]);
ReconPtr[1] = clamp255(RefPtr[1] + ChangePtr[1]);
ReconPtr[2] = clamp255(RefPtr[2] + ChangePtr[2]);
@@ -54,19 +69,19 @@
ReconPtr[6] = clamp255(RefPtr[6] + ChangePtr[6]);
ReconPtr[7] = clamp255(RefPtr[7] + ChangePtr[7]);
- ChangePtr += BLOCK_HEIGHT_WIDTH;
+ ChangePtr += 8;
ReconPtr += LineStep;
RefPtr += LineStep;
}
-
}
-void ReconInterHalfPixel2( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- unsigned char * RefPtr1, unsigned char * RefPtr2,
- ogg_int16_t * ChangePtr, ogg_uint32_t LineStep ) {
+static void recon_inter8x8_half__c (unsigned char *ReconPtr, unsigned char *RefPtr1,
+ unsigned char *RefPtr2, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep)
+{
ogg_uint32_t i;
- for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++ ){
+ for (i = 8; i; i--){
ReconPtr[0] = clamp255((((int)RefPtr1[0] + (int)RefPtr2[0]) >> 1) + ChangePtr[0] );
ReconPtr[1] = clamp255((((int)RefPtr1[1] + (int)RefPtr2[1]) >> 1) + ChangePtr[1] );
ReconPtr[2] = clamp255((((int)RefPtr1[2] + (int)RefPtr2[2]) >> 1) + ChangePtr[2] );
@@ -76,10 +91,20 @@
ReconPtr[6] = clamp255((((int)RefPtr1[6] + (int)RefPtr2[6]) >> 1) + ChangePtr[6] );
ReconPtr[7] = clamp255((((int)RefPtr1[7] + (int)RefPtr2[7]) >> 1) + ChangePtr[7] );
- ChangePtr += BLOCK_HEIGHT_WIDTH;
+ ChangePtr += 8;
ReconPtr += LineStep;
RefPtr1 += LineStep;
RefPtr2 += LineStep;
}
+}
+void dsp_recon_init (DspFunctions *funcs)
+{
+ funcs->copy8x8 = copy8x8__c;
+ funcs->recon_intra8x8 = recon_intra8x8__c;
+ funcs->recon_inter8x8 = recon_inter8x8__c;
+ funcs->recon_inter8x8_half = recon_inter8x8_half__c;
+ if (cpu_flags & CPU_X86_MMX) {
+ dsp_i386_mmx_recon_init(&dsp_funcs);
+ }
}
Index: lib/dct_encode.c
===================================================================
--- lib/dct_encode.c (revision 7621)
+++ lib/dct_encode.c (working copy)
@@ -17,110 +17,10 @@
#include <stdlib.h>
#include "encoder_internal.h"
+#include "dsp.h"
static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
-static void Sub8 (unsigned char *FiltPtr, unsigned char *ReconPtr,
- ogg_int16_t *DctInputPtr, unsigned char *old_ptr1,
- unsigned char *new_ptr1, ogg_uint32_t PixelsPerLine,
- ogg_uint32_t ReconPixelsPerLine ) {
- int i;
-
- /* For each block row */
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ){
- DctInputPtr[0] = (ogg_int16_t)((int)(FiltPtr[0]) - ((int)ReconPtr[0]) );
- DctInputPtr[1] = (ogg_int16_t)((int)(FiltPtr[1]) - ((int)ReconPtr[1]) );
- DctInputPtr[2] = (ogg_int16_t)((int)(FiltPtr[2]) - ((int)ReconPtr[2]) );
- DctInputPtr[3] = (ogg_int16_t)((int)(FiltPtr[3]) - ((int)ReconPtr[3]) );
- DctInputPtr[4] = (ogg_int16_t)((int)(FiltPtr[4]) - ((int)ReconPtr[4]) );
- DctInputPtr[5] = (ogg_int16_t)((int)(FiltPtr[5]) - ((int)ReconPtr[5]) );
- DctInputPtr[6] = (ogg_int16_t)((int)(FiltPtr[6]) - ((int)ReconPtr[6]) );
- DctInputPtr[7] = (ogg_int16_t)((int)(FiltPtr[7]) - ((int)ReconPtr[7]) );
-
- /* Update the screen canvas in one step*/
- ((ogg_uint32_t*)old_ptr1)[0] = ((ogg_uint32_t*)new_ptr1)[0];
- ((ogg_uint32_t*)old_ptr1)[1] = ((ogg_uint32_t*)new_ptr1)[1];
-
- /* Start next row */
- new_ptr1 += PixelsPerLine;
- old_ptr1 += PixelsPerLine;
- FiltPtr += PixelsPerLine;
- ReconPtr += ReconPixelsPerLine;
- DctInputPtr += BLOCK_HEIGHT_WIDTH;
- }
-}
-
-static void Sub8_128 (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr,
- unsigned char *old_ptr1, unsigned char *new_ptr1,
- ogg_uint32_t PixelsPerLine ) {
- int i;
- /* For each block row */
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ){
- /* INTRA mode so code raw image data */
- /* We convert the data to 8 bit signed (by subtracting 128) as
- this reduces the internal precision requirments in the DCT
- transform. */
- DctInputPtr[0] = (ogg_int16_t)((int)(FiltPtr[0]) - 128);
- DctInputPtr[1] = (ogg_int16_t)((int)(FiltPtr[1]) - 128);
- DctInputPtr[2] = (ogg_int16_t)((int)(FiltPtr[2]) - 128);
- DctInputPtr[3] = (ogg_int16_t)((int)(FiltPtr[3]) - 128);
- DctInputPtr[4] = (ogg_int16_t)((int)(FiltPtr[4]) - 128);
- DctInputPtr[5] = (ogg_int16_t)((int)(FiltPtr[5]) - 128);
- DctInputPtr[6] = (ogg_int16_t)((int)(FiltPtr[6]) - 128);
- DctInputPtr[7] = (ogg_int16_t)((int)(FiltPtr[7]) - 128);
-
- /* Update the screen canvas in one step */
- ((ogg_uint32_t*)old_ptr1)[0] = ((ogg_uint32_t*)new_ptr1)[0];
- ((ogg_uint32_t*)old_ptr1)[1] = ((ogg_uint32_t*)new_ptr1)[1];
-
- /* Start next row */
- new_ptr1 += PixelsPerLine;
- old_ptr1 += PixelsPerLine;
- FiltPtr += PixelsPerLine;
- DctInputPtr += BLOCK_HEIGHT_WIDTH;
- }
-}
-
-static void Sub8Av2 (unsigned char *FiltPtr, unsigned char *ReconPtr1,
- unsigned char *ReconPtr2, ogg_int16_t *DctInputPtr,
- unsigned char *old_ptr1, unsigned char *new_ptr1,
- ogg_uint32_t PixelsPerLine,
- ogg_uint32_t ReconPixelsPerLine ) {
- int i;
-
- /* For each block row */
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ) {
- DctInputPtr[0] = (ogg_int16_t)
- ((int)(FiltPtr[0]) - (((int)ReconPtr1[0] + (int)ReconPtr2[0]) / 2) );
- DctInputPtr[1] = (ogg_int16_t)
- ((int)(FiltPtr[1]) - (((int)ReconPtr1[1] + (int)ReconPtr2[1]) / 2) );
- DctInputPtr[2] = (ogg_int16_t)
- ((int)(FiltPtr[2]) - (((int)ReconPtr1[2] + (int)ReconPtr2[2]) / 2) );
- DctInputPtr[3] = (ogg_int16_t)
- ((int)(FiltPtr[3]) - (((int)ReconPtr1[3] + (int)ReconPtr2[3]) / 2) );
- DctInputPtr[4] = (ogg_int16_t)
- ((int)(FiltPtr[4]) - (((int)ReconPtr1[4] + (int)ReconPtr2[4]) / 2) );
- DctInputPtr[5] = (ogg_int16_t)
- ((int)(FiltPtr[5]) - (((int)ReconPtr1[5] + (int)ReconPtr2[5]) / 2) );
- DctInputPtr[6] = (ogg_int16_t)
- ((int)(FiltPtr[6]) - (((int)ReconPtr1[6] + (int)ReconPtr2[6]) / 2) );
- DctInputPtr[7] = (ogg_int16_t)
- ((int)(FiltPtr[7]) - (((int)ReconPtr1[7] + (int)ReconPtr2[7]) / 2) );
-
- /* Update the screen canvas in one step */
- ((ogg_uint32_t*)old_ptr1)[0] = ((ogg_uint32_t*)new_ptr1)[0];
- ((ogg_uint32_t*)old_ptr1)[1] = ((ogg_uint32_t*)new_ptr1)[1];
-
- /* Start next row */
- new_ptr1 += PixelsPerLine;
- old_ptr1 += PixelsPerLine;
- FiltPtr += PixelsPerLine;
- ReconPtr1 += ReconPixelsPerLine;
- ReconPtr2 += ReconPixelsPerLine;
- DctInputPtr += BLOCK_HEIGHT_WIDTH;
- }
-}
-
static unsigned char TokenizeDctValue (ogg_int16_t DataValue,
ogg_uint32_t * TokenListPtr ){
unsigned char tokens_added = 0;
@@ -452,13 +352,15 @@
/* Is the MV offset exactly pixel alligned */
if ( AbsRefOffset == 0 ){
- Sub8( FiltPtr, ReconPtr1, DctInputPtr, old_ptr1, new_ptr1,
- PixelsPerLine, ReconPixelsPerLine );
+ dsp_static_sub8x8( FiltPtr, ReconPtr1, DctInputPtr,
+ PixelsPerLine, ReconPixelsPerLine);
+ dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
} else {
/* Fractional pixel MVs. */
/* Note that we only use two pixel values even for the diagonal */
- Sub8Av2(FiltPtr, ReconPtr1,ReconPtr2,DctInputPtr, old_ptr1,
- new_ptr1, PixelsPerLine, ReconPixelsPerLine );
+ dsp_static_sub8x8avg2(FiltPtr, ReconPtr1,ReconPtr2,DctInputPtr,
+ PixelsPerLine, ReconPixelsPerLine);
+ dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
}
}
@@ -534,17 +436,18 @@
pb.GoldenFrame[cpi->pb.recon_pixel_index_table[FragIndex]];
}
- Sub8( FiltPtr, ReconPtr1, DctInputPtr, old_ptr1, new_ptr1,
- PixelsPerLine, ReconPixelsPerLine );
+ dsp_static_sub8x8( FiltPtr, ReconPtr1, DctInputPtr,
+ PixelsPerLine, ReconPixelsPerLine);
+ dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
} else if ( cpi->pb.CodingMode==CODE_INTRA ) {
- Sub8_128(FiltPtr, DctInputPtr, old_ptr1, new_ptr1, PixelsPerLine);
-
+ dsp_static_sub8x8_128(FiltPtr, DctInputPtr, PixelsPerLine);
+ dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
}
/* Proceed to encode the data into the encode buffer if the encoder
is enabled. */
/* Perform a 2D DCT transform on the data. */
- fdct_short( cpi->DCTDataBuffer, cpi->DCT_codes );
+ dsp_static_fdct_short( cpi->DCTDataBuffer, cpi->DCT_codes );
/* Quantize that transform data. */
quantize ( &cpi->pb, cpi->DCT_codes, cpi->pb.QFragData[FragIndex] );
Index: lib/cpu.c
===================================================================
--- lib/cpu.c (revision 0)
+++ lib/cpu.c (revision 0)
@@ -0,0 +1,107 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include "cpu.h"
+
+ogg_uint32_t cpu_flags = 0;
+
+#if 1
+static ogg_uint32_t cpu_get_flags (void)
+{
+ ogg_uint32_t eax, ebx, ecx, edx;
+ ogg_uint32_t flags;
+
+#define cpuid(op,eax,ebx,ecx,edx) \
+ asm volatile ("pushl %%ebx \n\t" \
+ "cpuid \n\t" \
+ "movl %%ebx,%1 \n\t" \
+ "popl %%ebx" \
+ : "=a" (eax), \
+ "=r" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+
+ asm volatile ("pushfl \n\t"
+ "pushfl \n\t"
+ "popl %0 \n\t"
+ "movl %0,%1 \n\t"
+ "xorl $0x200000,%0 \n\t"
+ "pushl %0 \n\t"
+ "popfl \n\t"
+ "pushfl \n\t"
+ "popl %0 \n\t"
+ "popfl"
+ : "=r" (eax),
+ "=r" (ebx)
+ :
+ : "cc");
+
+ if (eax == ebx) /* no cpuid */
+ return 0;
+
+ cpuid(0, eax, ebx, ecx, edx);
+
+ if (ebx == 0x756e6547 &&
+ edx == 0x49656e69 &&
+ ecx == 0x6c65746e) {
+ /* intel */
+
+ inteltest:
+ cpuid(1, eax, ebx, ecx, edx);
+ if ((edx & 0x00800000) == 0)
+ return 0;
+ flags = CPU_X86_MMX;
+ if (edx & 0x02000000)
+ flags |= CPU_X86_MMXEXT | CPU_X86_SSE;
+ if (edx & 0x04000000)
+ flags |= CPU_X86_SSE2;
+ return flags;
+ } else if (ebx == 0x68747541 &&
+ edx == 0x69746e65 &&
+ ecx == 0x444d4163) {
+ /* AMD */
+ cpuid(0x80000000, eax, ebx, ecx, edx);
+ if ((unsigned)eax < 0x80000001)
+ goto inteltest;
+ cpuid(0x80000001, eax, ebx, ecx, edx);
+ if ((edx & 0x00800000) == 0)
+ return 0;
+ flags = CPU_X86_MMX;
+ if (edx & 0x80000000)
+ flags |= CPU_X86_3DNOW;
+ if (edx & 0x00400000)
+ flags |= CPU_X86_MMXEXT;
+ return flags;
+ }
+ else {
+ /* implement me */
+ }
+
+ return flags;
+}
+#else
+static ogg_uint32_t cpu_get_flags (void) {
+ return 0;
+}
+#endif
+
+void cpu_init ()
+{
+ cpu_flags = cpu_get_flags();
+}
Index: lib/cpu.h
===================================================================
--- lib/cpu.h (revision 0)
+++ lib/cpu.h (revision 0)
@@ -0,0 +1,28 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include "encoder_internal.h"
+
+extern ogg_uint32_t cpu_flags;
+
+#define CPU_X86_MMX (1<<0)
+#define CPU_X86_3DNOW (1<<1)
+#define CPU_X86_MMXEXT (1<<2)
+#define CPU_X86_SSE (1<<3)
+#define CPU_X86_SSE2 (1<<4)
+
+void cpu_init () ;
Index: lib/i386/fdct_mmx.c
===================================================================
--- lib/i386/fdct_mmx.c (revision 0)
+++ lib/i386/fdct_mmx.c (revision 0)
@@ -0,0 +1,340 @@
+;//==========================================================================
+;//
+;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+;// PURPOSE.
+;//
+;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
+;//
+;//--------------------------------------------------------------------------
+
+#include <theora/theora.h>
+#include "dsp.h"
+
+static const __attribute__ ((aligned(8))) ogg_int64_t xC1S7 = 0x0fb15fb15fb15fb15LL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC2S6 = 0x0ec83ec83ec83ec83LL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC3S5 = 0x0d4dbd4dbd4dbd4dbLL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC4S4 = 0x0b505b505b505b505LL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC5S3 = 0x08e3a8e3a8e3a8e3aLL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC6S2 = 0x061f861f861f861f8LL;
+static const __attribute__ ((aligned(8))) ogg_int64_t xC7S1 = 0x031f131f131f131f1LL;
+
+#if defined(__MINGW32__) || defined(__CYGWIN__) || \
+ defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
+# define M(a) "_" #a
+#else
+# define M(a) #a
+#endif
+
+/***********************************************************************
+ * File: fdct_m.asm
+ *
+ * Description:
+ * This function perform 2-D Forward DCT on a 8x8 block
+ *
+ *
+ * Input: Pointers to input source data buffer and destination
+ * buffer.
+ *
+ * Note: none
+ *
+ * Special Notes: We try to do the truncation right to match the result
+ * of the c version.
+ *
+ ************************************************************************/
+
+/* execute stage 1 of forward DCT */
+#define Fdct_mmx(ip0,ip1,ip2,ip3,ip4,ip5,ip6,ip7,temp) \
+ " movq " #ip0 ", %%mm0 \n\t" \
+ " movq " #ip1 ", %%mm1 \n\t" \
+ " movq " #ip3 ", %%mm2 \n\t" \
+ " movq " #ip5 ", %%mm3 \n\t" \
+ " movq %%mm0, %%mm4 \n\t" \
+ " movq %%mm1, %%mm5 \n\t" \
+ " movq %%mm2, %%mm6 \n\t" \
+ " movq %%mm3, %%mm7 \n\t" \
+ \
+ " paddsw " #ip7 ", %%mm0 \n\t" /* mm0 = ip0 + ip7 = is07 */ \
+ " paddsw " #ip2 ", %%mm1 \n\t" /* mm1 = ip1 + ip2 = is12 */ \
+ " paddsw " #ip4 ", %%mm2 \n\t" /* mm2 = ip3 + ip4 = is34 */ \
+ " paddsw " #ip6 ", %%mm3 \n\t" /* mm3 = ip5 + ip6 = is56 */ \
+ " psubsw " #ip7 ", %%mm4 \n\t" /* mm4 = ip0 - ip7 = id07 */ \
+ " psubsw " #ip2 ", %%mm5 \n\t" /* mm5 = ip1 - ip2 = id12 */ \
+ \
+ " psubsw %%mm2, %%mm0 \n\t" /* mm0 = is07 - is34 */ \
+ \
+ " paddsw %%mm2, %%mm2 \n\t" \
+ \
+ " psubsw " #ip4 ", %%mm6 \n\t" /* mm6 = ip3 - ip4 = id34 */ \
+ \
+ " paddsw %%mm0, %%mm2 \n\t" /* mm2 = is07 + is34 = is0734 */ \
+ " psubsw %%mm3, %%mm1 \n\t" /* mm1 = is12 - is56 */ \
+ " movq %%mm0," #temp " \n\t" /* Save is07 - is34 to free mm0; */ \
+ " paddsw %%mm3, %%mm3 \n\t" \
+ " paddsw %%mm1, %%mm3 \n\t" /* mm3 = is12 + 1s56 = is1256 */ \
+ \
+ " psubsw " #ip6 ", %%mm7 \n\t" /* mm7 = ip5 - ip6 = id56 */ \
+ /* ------------------------------------------------------------------- */ \
+ " psubsw %%mm7, %%mm5 \n\t" /* mm5 = id12 - id56 */ \
+ " paddsw %%mm7, %%mm7 \n\t" \
+ " paddsw %%mm5, %%mm7 \n\t" /* mm7 = id12 + id56 */ \
+ /* ------------------------------------------------------------------- */ \
+ " psubsw %%mm3, %%mm2 \n\t" /* mm2 = is0734 - is1256 */ \
+ " paddsw %%mm3, %%mm3 \n\t" \
+ \
+ " movq %%mm2, %%mm0 \n\t" /* make a copy */ \
+ " paddsw %%mm2, %%mm3 \n\t" /* mm3 = is0734 + is1256 */ \
+ \
+ " pmulhw "M(xC4S4)", %%mm0 \n\t" /* mm0 = xC4S4 * ( is0734 - is1256 ) - ( is0734 - is1256 ) */ \
+ " paddw %%mm2, %%mm0 \n\t" /* mm0 = xC4S4 * ( is0734 - is1256 ) */ \
+ " psrlw $15, %%mm2 \n\t" \
+ " paddw %%mm2, %%mm0 \n\t" /* Truncate mm0, now it is op[4] */ \
+ \
+ " movq %%mm3, %%mm2 \n\t" \
+ " movq %%mm0," #ip4 " \n\t" /* save ip4, now mm0,mm2 are free */ \
+ \
+ " movq %%mm3, %%mm0 \n\t" \
+ " pmulhw "M(xC4S4)", %%mm3 \n\t" /* mm3 = xC4S4 * ( is0734 +is1256 ) - ( is0734 +is1256 ) */ \
+ \
+ " psrlw $15, %%mm2 \n\t" \
+ " paddw %%mm0, %%mm3 \n\t" /* mm3 = xC4S4 * ( is0734 +is1256 ) */ \
+ " paddw %%mm2, %%mm3 \n\t" /* Truncate mm3, now it is op[0] */ \
+ \
+ " movq %%mm3," #ip0 " \n\t" \
+ /* ------------------------------------------------------------------- */ \
+ " movq " #temp ", %%mm3 \n\t" /* mm3 = irot_input_y */ \
+ " pmulhw "M(xC2S6)", %%mm3 \n\t" /* mm3 = xC2S6 * irot_input_y - irot_input_y */ \
+ \
+ " movq " #temp ", %%mm2 \n\t" \
+ " movq %%mm2, %%mm0 \n\t" \
+ \
+ " psrlw $15, %%mm2 \n\t" /* mm3 = xC2S6 * irot_input_y */ \
+ " paddw %%mm0, %%mm3 \n\t" \
+ \
+ " paddw %%mm2, %%mm3 \n\t" /* Truncated */ \
+ " movq %%mm5, %%mm0 \n\t" \
+ \
+ " movq %%mm5, %%mm2 \n\t" \
+ " pmulhw "M(xC6S2)", %%mm0 \n\t" /* mm0 = xC6S2 * irot_input_x */ \
+ \
+ " psrlw $15, %%mm2 \n\t" \
+ " paddw %%mm2, %%mm0 \n\t" /* Truncated */ \
+ \
+ " paddsw %%mm0, %%mm3 \n\t" /* ip[2] */ \
+ " movq %%mm3," #ip2 " \n\t" /* Save ip2 */ \
+ \
+ " movq %%mm5, %%mm0 \n\t" \
+ " movq %%mm5, %%mm2 \n\t" \
+ \
+ " pmulhw "M(xC2S6)", %%mm5 \n\t" /* mm5 = xC2S6 * irot_input_x - irot_input_x */ \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " movq " #temp ", %%mm3 \n\t" \
+ " paddw %%mm0, %%mm5 \n\t" /* mm5 = xC2S6 * irot_input_x */ \
+ \
+ " paddw %%mm2, %%mm5 \n\t" /* Truncated */ \
+ " movq %%mm3, %%mm2 \n\t" \
+ \
+ " pmulhw "M(xC6S2)", %%mm3 \n\t" /* mm3 = xC6S2 * irot_input_y */ \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " paddw %%mm2, %%mm3 \n\t" /* Truncated */ \
+ " psubsw %%mm5, %%mm3 \n\t" \
+ \
+ " movq %%mm3," #ip6 " \n\t" \
+ /* ------------------------------------------------------------------- */ \
+ " movq "M(xC4S4)", %%mm0 \n\t" \
+ " movq %%mm1, %%mm2 \n\t" \
+ " movq %%mm1, %%mm3 \n\t" \
+ \
+ " pmulhw %%mm0, %%mm1 \n\t" /* mm0 = xC4S4 * ( is12 - is56 ) - ( is12 - is56 ) */ \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " paddw %%mm3, %%mm1 \n\t" /* mm0 = xC4S4 * ( is12 - is56 ) */ \
+ " paddw %%mm2, %%mm1 \n\t" /* Truncate mm1, now it is icommon_product1 */ \
+ \
+ " movq %%mm7, %%mm2 \n\t" \
+ " movq %%mm7, %%mm3 \n\t" \
+ \
+ " pmulhw %%mm0, %%mm7 \n\t" /* mm7 = xC4S4 * ( id12 + id56 ) - ( id12 + id56 ) */ \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " paddw %%mm3, %%mm7 \n\t" /* mm7 = xC4S4 * ( id12 + id56 ) */ \
+ " paddw %%mm2, %%mm7 \n\t" /* Truncate mm7, now it is icommon_product2 */ \
+ /* ------------------------------------------------------------------- */ \
+ " pxor %%mm0, %%mm0 \n\t" /* Clear mm0 */ \
+ " psubsw %%mm6, %%mm0 \n\t" /* mm0 = - id34 */ \
+ \
+ " psubsw %%mm7, %%mm0 \n\t" /* mm0 = - ( id34 + idcommon_product2 ) */ \
+ " paddsw %%mm6, %%mm6 \n\t" \
+ " paddsw %%mm0, %%mm6 \n\t" /* mm6 = id34 - icommon_product2 */ \
+ \
+ " psubsw %%mm1, %%mm4 \n\t" /* mm4 = id07 - icommon_product1 */ \
+ " paddsw %%mm1, %%mm1 \n\t" \
+ " paddsw %%mm4, %%mm1 \n\t" /* mm1 = id07 + icommon_product1 */ \
+ /* ------------------------------------------------------------------- */ \
+ " movq "M(xC1S7)", %%mm7 \n\t" \
+ " movq %%mm1, %%mm2 \n\t" \
+ \
+ " movq %%mm1, %%mm3 \n\t" \
+ " pmulhw %%mm7, %%mm1 \n\t" /* mm1 = xC1S7 * irot_input_x - irot_input_x */ \
+ \
+ " movq "M(xC7S1)", %%mm7 \n\t" \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " paddw %%mm3, %%mm1 \n\t" /* mm1 = xC1S7 * irot_input_x */ \
+ " paddw %%mm2, %%mm1 \n\t" /* Trucated */ \
+ \
+ " pmulhw %%mm7, %%mm3 \n\t" /* mm3 = xC7S1 * irot_input_x */ \
+ " paddw %%mm2, %%mm3 \n\t" /* Truncated */ \
+ \
+ " movq %%mm0, %%mm5 \n\t" \
+ " movq %%mm0, %%mm2 \n\t" \
+ \
+ " movq "M(xC1S7)", %%mm7 \n\t" \
+ " pmulhw %%mm7, %%mm0 \n\t" /* mm0 = xC1S7 * irot_input_y - irot_input_y */ \
+ \
+ " movq "M(xC7S1)", %%mm7 \n\t" \
+ " psrlw $15, %%mm2 \n\t" \
+ \
+ " paddw %%mm5, %%mm0 \n\t" /* mm0 = xC1S7 * irot_input_y */ \
+ " paddw %%mm2, %%mm0 \n\t" /* Truncated */ \
+ \
+ " pmulhw %%mm7, %%mm5 \n\t" /* mm5 = xC7S1 * irot_input_y */ \
+ " paddw %%mm2, %%mm5 \n\t" /* Truncated */ \
+ \
+ " psubsw %%mm5, %%mm1 \n\t" /* mm1 = xC1S7 * irot_input_x - xC7S1 * irot_input_y = ip1 */ \
+ " paddsw %%mm0, %%mm3 \n\t" /* mm3 = xC7S1 * irot_input_x - xC1S7 * irot_input_y = ip7 */ \
+ \
+ " movq %%mm1," #ip1 " \n\t" \
+ " movq %%mm3," #ip7 " \n\t" \
+ /* ------------------------------------------------------------------- */ \
+ " movq "M(xC3S5)", %%mm0 \n\t" \
+ " movq "M(xC5S3)", %%mm1 \n\t" \
+ \
+ " movq %%mm6, %%mm5 \n\t" \
+ " movq %%mm6, %%mm7 \n\t" \
+ \
+ " movq %%mm4, %%mm2 \n\t" \
+ " movq %%mm4, %%mm3 \n\t" \
+ \
+ " pmulhw %%mm0, %%mm4 \n\t" /* mm4 = xC3S5 * irot_input_x - irot_input_x */ \
+ " pmulhw %%mm1, %%mm6 \n\t" /* mm6 = xC5S3 * irot_input_y - irot_input_y */ \
+ \
+ " psrlw $15, %%mm2 \n\t" \
+ " psrlw $15, %%mm5 \n\t" \
+ \
+ " paddw %%mm3, %%mm4 \n\t" /* mm4 = xC3S5 * irot_input_x */ \
+ " paddw %%mm7, %%mm6 \n\t" /* mm6 = xC5S3 * irot_input_y */ \
+ \
+ " paddw %%mm2, %%mm4 \n\t" /* Truncated */ \
+ " paddw %%mm5, %%mm6 \n\t" /* Truncated */ \
+ \
+ " psubsw %%mm6, %%mm4 \n\t" /* ip3 */ \
+ " movq %%mm4," #ip3 " \n\t" \
+ \
+ " movq %%mm3, %%mm4 \n\t" \
+ " movq %%mm7, %%mm6 \n\t" \
+ \
+ " pmulhw %%mm1, %%mm3 \n\t" /* mm3 = xC5S3 * irot_input_x - irot_input_x */ \
+ " pmulhw %%mm0, %%mm7 \n\t" /* mm7 = xC3S5 * irot_input_y - irot_input_y */ \
+ \
+ " paddw %%mm2, %%mm4 \n\t" \
+ " paddw %%mm5, %%mm6 \n\t" \
+ \
+ " paddw %%mm4, %%mm3 \n\t" /* mm3 = xC5S3 * irot_input_x */ \
+ " paddw %%mm6, %%mm7 \n\t" /* mm7 = xC3S5 * irot_input_y */ \
+ \
+ " paddw %%mm7, %%mm3 \n\t" /* ip5 */ \
+ " movq %%mm3," #ip5 " \n\t"
+
+#define Transpose_mmx(ip0,ip1,ip2,ip3,ip4,ip5,ip6,ip7, \
+ op0,op1,op2,op3,op4,op5,op6,op7) \
+ " movq " #ip0 ", %%mm0 \n\t" /* mm0 = a0 a1 a2 a3 */ \
+ " movq " #ip4 ", %%mm4 \n\t" /* mm4 = e4 e5 e6 e7 */ \
+ " movq " #ip1 ", %%mm1 \n\t" /* mm1 = b0 b1 b2 b3 */ \
+ " movq " #ip5 ", %%mm5 \n\t" /* mm5 = f4 f5 f6 f7 */ \
+ " movq " #ip2 ", %%mm2 \n\t" /* mm2 = c0 c1 c2 c3 */ \
+ " movq " #ip6 ", %%mm6 \n\t" /* mm6 = g4 g5 g6 g7 */ \
+ " movq " #ip3 ", %%mm3 \n\t" /* mm3 = d0 d1 d2 d3 */ \
+ " movq %%mm1," #op1 " \n\t" /* save b0 b1 b2 b3 */ \
+ " movq " #ip7 ", %%mm7 \n\t" /* mm7 = h0 h1 h2 h3 */ \
+ /* Transpose 2x8 block */ \
+ " movq %%mm4, %%mm1 \n\t" /* mm1 = e3 e2 e1 e0 */ \
+ " punpcklwd %%mm5, %%mm4 \n\t" /* mm4 = f1 e1 f0 e0 */ \
+ " movq %%mm0," #op0 " \n\t" /* save a3 a2 a1 a0 */ \
+ " punpckhwd %%mm5, %%mm1 \n\t" /* mm1 = f3 e3 f2 e2 */ \
+ " movq %%mm6, %%mm0 \n\t" /* mm0 = g3 g2 g1 g0 */ \
+ " punpcklwd %%mm7, %%mm6 \n\t" /* mm6 = h1 g1 h0 g0 */ \
+ " movq %%mm4, %%mm5 \n\t" /* mm5 = f1 e1 f0 e0 */ \
+ " punpckldq %%mm6, %%mm4 \n\t" /* mm4 = h0 g0 f0 e0 = MM4 */ \
+ " punpckhdq %%mm6, %%mm5 \n\t" /* mm5 = h1 g1 f1 e1 = MM5 */ \
+ " movq %%mm1, %%mm6 \n\t" /* mm6 = f3 e3 f2 e2 */ \
+ " movq %%mm4," #op4 " \n\t" \
+ " punpckhwd %%mm7, %%mm0 \n\t" /* mm0 = h3 g3 h2 g2 */ \
+ " movq %%mm5," #op5 " \n\t" \
+ " punpckhdq %%mm0, %%mm6 \n\t" /* mm6 = h3 g3 f3 e3 = MM7 */ \
+ " movq " #op0 ", %%mm4 \n\t" /* mm4 = a3 a2 a1 a0 */ \
+ " punpckldq %%mm0, %%mm1 \n\t" /* mm1 = h2 g2 f2 e2 = MM6 */ \
+ " movq " #op1 ", %%mm5 \n\t" /* mm5 = b3 b2 b1 b0 */ \
+ " movq %%mm4, %%mm0 \n\t" /* mm0 = a3 a2 a1 a0 */ \
+ " movq %%mm6," #op7 " \n\t" \
+ " punpcklwd %%mm5, %%mm0 \n\t" /* mm0 = b1 a1 b0 a0 */ \
+ " movq %%mm1," #op6 " \n\t" \
+ " punpckhwd %%mm5, %%mm4 \n\t" /* mm4 = b3 a3 b2 a2 */ \
+ " movq %%mm2, %%mm5 \n\t" /* mm5 = c3 c2 c1 c0 */ \
+ " punpcklwd %%mm3, %%mm2 \n\t" /* mm2 = d1 c1 d0 c0 */ \
+ " movq %%mm0, %%mm1 \n\t" /* mm1 = b1 a1 b0 a0 */ \
+ " punpckldq %%mm2, %%mm0 \n\t" /* mm0 = d0 c0 b0 a0 = MM0 */ \
+ " punpckhdq %%mm2, %%mm1 \n\t" /* mm1 = d1 c1 b1 a1 = MM1 */ \
+ " movq %%mm4, %%mm2 \n\t" /* mm2 = b3 a3 b2 a2 */ \
+ " movq %%mm0," #op0 " \n\t" \
+ " punpckhwd %%mm3, %%mm5 \n\t" /* mm5 = d3 c3 d2 c2 */ \
+ " movq %%mm1," #op1 " \n\t" \
+ " punpckhdq %%mm5, %%mm4 \n\t" /* mm4 = d3 c3 b3 a3 = MM3 */ \
+ " punpckldq %%mm5, %%mm2 \n\t" /* mm2 = d2 c2 b2 a2 = MM2 */ \
+ " movq %%mm4," #op3 " \n\t" \
+ " movq %%mm2," #op2 " \n\t"
+
+
+static void fdct_short__mmx ( ogg_int16_t *InputData, ogg_int16_t *OutputData)
+{
+ ogg_int64_t __attribute__((aligned(8))) align_tmp[16];
+ ogg_int16_t *const temp= (int16_t*)align_tmp;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+ /*
+ * Input data is an 8x8 block. To make processing of the data more efficent
+ * we will transpose the block of data to two 4x8 blocks???
+ */
+ Transpose_mmx ( (%0), 16(%0), 32(%0), 48(%0), 8(%0), 24(%0), 40(%0), 56(%0),
+ (%1), 16(%1), 32(%1), 48(%1), 8(%1), 24(%1), 40(%1), 56(%1))
+ Fdct_mmx ( (%1), 16(%1), 32(%1), 48(%1), 8(%1), 24(%1), 40(%1), 56(%1), (%2))
+
+ Transpose_mmx (64(%0), 80(%0), 96(%0),112(%0), 72(%0), 88(%0),104(%0),120(%0),
+ 64(%1), 80(%1), 96(%1),112(%1), 72(%1), 88(%1),104(%1),120(%1))
+ Fdct_mmx (64(%1), 80(%1), 96(%1),112(%1), 72(%1), 88(%1),104(%1),120(%1), (%2))
+
+ Transpose_mmx ( 0(%1), 16(%1), 32(%1), 48(%1), 64(%1), 80(%1), 96(%1),112(%1),
+ 0(%1), 16(%1), 32(%1), 48(%1), 64(%1), 80(%1), 96(%1),112(%1))
+ Fdct_mmx ( 0(%1), 16(%1), 32(%1), 48(%1), 64(%1), 80(%1), 96(%1),112(%1), (%2))
+
+ Transpose_mmx ( 8(%1), 24(%1), 40(%1), 56(%1), 72(%1), 88(%1),104(%1),120(%1),
+ 8(%1), 24(%1), 40(%1), 56(%1), 72(%1), 88(%1),104(%1),120(%1))
+ Fdct_mmx ( 8(%1), 24(%1), 40(%1), 56(%1), 72(%1), 88(%1),104(%1),120(%1), (%2))
+
+ " emms \n\t"
+
+ : "+r" (InputData),
+ "+r" (OutputData)
+ : "r" (temp)
+ : "memory"
+ );
+}
+
+void dsp_i386_mmx_fdct_init(DspFunctions *funcs)
+{
+ funcs->fdct_short = fdct_short__mmx;
+}
Index: lib/i386/dsp_mmx.c
===================================================================
--- lib/i386/dsp_mmx.c (revision 0)
+++ lib/i386/dsp_mmx.c (revision 0)
@@ -0,0 +1,642 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include "dsp.h"
+
+static const __attribute__ ((aligned(8))) ogg_int64_t V128 = 0x0080008000800080LL;
+
+#if defined(__MINGW32__) || defined(__CYGWIN__) || \
+ defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
+# define M(a) "_" #a
+#else
+# define M(a) #a
+#endif
+
+#define DSP_OP_AVG(a,b) ((((int)(a)) + ((int)(b)))/2)
+#define DSP_OP_DIFF(a,b) (((int)(a)) - ((int)(b)))
+#define DSP_OP_ABS_DIFF(a,b) abs((((int)(a)) - ((int)(b))))
+
+static void sub8x8__mmx (unsigned char *FiltPtr, unsigned char *ReconPtr,
+ ogg_int16_t *DctInputPtr, ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm7, %%mm7 \n\t"
+
+ ".rept 8 \n\t"
+ " movq (%0), %%mm0 \n\t" /* mm0 = FiltPtr */
+ " movq (%1), %%mm1 \n\t" /* mm1 = ReconPtr */
+ " movq %%mm0, %%mm2 \n\t" /* dup to prepare for up conversion */
+ " movq %%mm1, %%mm3 \n\t" /* dup to prepare for up conversion */
+ /* convert from UINT8 to INT16 */
+ " punpcklbw %%mm7, %%mm0 \n\t" /* mm0 = INT16(FiltPtr) */
+ " punpcklbw %%mm7, %%mm1 \n\t" /* mm1 = INT16(ReconPtr) */
+ " punpckhbw %%mm7, %%mm2 \n\t" /* mm2 = INT16(FiltPtr) */
+ " punpckhbw %%mm7, %%mm3 \n\t" /* mm3 = INT16(ReconPtr) */
+ /* start calculation */
+ " psubw %%mm1, %%mm0 \n\t" /* mm0 = FiltPtr - ReconPtr */
+ " psubw %%mm3, %%mm2 \n\t" /* mm2 = FiltPtr - ReconPtr */
+ " movq %%mm0, (%2) \n\t" /* write answer out */
+ " movq %%mm2, 8(%2) \n\t" /* write answer out */
+ /* Increment pointers */
+ " add $16, %2 \n\t"
+ " add %3, %0 \n\t"
+ " add %4, %1 \n\t"
+ ".endr \n\t"
+
+ : "+r" (FiltPtr),
+ "+r" (ReconPtr),
+ "+r" (DctInputPtr)
+ : "m" (PixelsPerLine),
+ "m" (ReconPixelsPerLine)
+ : "memory"
+ );
+}
+
+static void sub8x8_128__mmx (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm7, %%mm7 \n\t"
+ " movq "M(V128)", %%mm1 \n\t"
+
+ ".rept 8 \n\t"
+ " movq (%0), %%mm0 \n\t" /* mm0 = FiltPtr */
+ " movq %%mm0, %%mm2 \n\t" /* dup to prepare for up conversion */
+ /* convert from UINT8 to INT16 */
+ " punpcklbw %%mm7, %%mm0 \n\t" /* mm0 = INT16(FiltPtr) */
+ " punpckhbw %%mm7, %%mm2 \n\t" /* mm2 = INT16(FiltPtr) */
+ /* start calculation */
+ " psubw %%mm1, %%mm0 \n\t" /* mm0 = FiltPtr - 128 */
+ " psubw %%mm1, %%mm2 \n\t" /* mm2 = FiltPtr - 128 */
+ " movq %%mm0, (%1) \n\t" /* write answer out */
+ " movq %%mm2, 8(%1) \n\t" /* write answer out */
+ /* Increment pointers */
+ " add $16, %1 \n\t"
+ " add %2, %0 \n\t"
+ ".endr \n\t"
+
+ : "+r" (FiltPtr),
+ "+r" (DctInputPtr)
+ : "m" (PixelsPerLine)
+ : "memory"
+ );
+}
+
+static void sub8x8avg2__mmx (unsigned char *FiltPtr, unsigned char *ReconPtr1,
+ unsigned char *ReconPtr2, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm7, %%mm7 \n\t"
+
+ ".rept 8 \n\t"
+ " movq (%0), %%mm0 \n\t" /* mm0 = FiltPtr */
+ " movq (%1), %%mm1 \n\t" /* mm1 = ReconPtr1 */
+ " movq (%2), %%mm4 \n\t" /* mm1 = ReconPtr2 */
+ " movq %%mm0, %%mm2 \n\t" /* dup to prepare for up conversion */
+ " movq %%mm1, %%mm3 \n\t" /* dup to prepare for up conversion */
+ " movq %%mm4, %%mm5 \n\t" /* dup to prepare for up conversion */
+ /* convert from UINT8 to INT16 */
+ " punpcklbw %%mm7, %%mm0 \n\t" /* mm0 = INT16(FiltPtr) */
+ " punpcklbw %%mm7, %%mm1 \n\t" /* mm1 = INT16(ReconPtr1) */
+ " punpcklbw %%mm7, %%mm4 \n\t" /* mm1 = INT16(ReconPtr2) */
+ " punpckhbw %%mm7, %%mm2 \n\t" /* mm2 = INT16(FiltPtr) */
+ " punpckhbw %%mm7, %%mm3 \n\t" /* mm3 = INT16(ReconPtr1) */
+ " punpckhbw %%mm7, %%mm5 \n\t" /* mm3 = INT16(ReconPtr2) */
+ /* average ReconPtr1 and ReconPtr2 */
+ " paddw %%mm4, %%mm1 \n\t" /* mm1 = ReconPtr1 + ReconPtr2 */
+ " paddw %%mm5, %%mm3 \n\t" /* mm3 = ReconPtr1 + ReconPtr2 */
+ " psrlw $1, %%mm1 \n\t" /* mm1 = (ReconPtr1 + ReconPtr2) / 2 */
+ " psrlw $1, %%mm3 \n\t" /* mm3 = (ReconPtr1 + ReconPtr2) / 2 */
+ " psubw %%mm1, %%mm0 \n\t" /* mm0 = FiltPtr - ((ReconPtr1 + ReconPtr2) / 2) */
+ " psubw %%mm3, %%mm2 \n\t" /* mm2 = FiltPtr - ((ReconPtr1 + ReconPtr2) / 2) */
+ " movq %%mm0, (%3) \n\t" /* write answer out */
+ " movq %%mm2, 8(%3) \n\t" /* write answer out */
+ /* Increment pointers */
+ " add $16, %3 \n\t"
+ " add %4, %0 \n\t"
+ " add %5, %1 \n\t"
+ " add %5, %2 \n\t"
+ ".endr \n\t"
+
+ : "+r" (FiltPtr),
+ "+r" (ReconPtr1),
+ "+r" (ReconPtr2),
+ "+r" (DctInputPtr)
+ : "m" (PixelsPerLine),
+ "m" (ReconPixelsPerLine)
+ : "memory"
+ );
+}
+
+static ogg_uint32_t row_sad8__mmx (unsigned char *Src1, unsigned char *Src2)
+{
+ ogg_uint32_t MaxSad;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm6, %%mm6 \n\t" /* zero out mm6 for unpack */
+ " pxor %%mm7, %%mm7 \n\t" /* zero out mm7 for unpack */
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+
+ " movq %%mm0, %%mm2 \n\t"
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t" /* ; unpack low four bytes to higher precision */
+ " punpckhbw %%mm7, %%mm1 \n\t" /* ; unpack high four bytes to higher precision */
+
+ " movq %%mm0, %%mm2 \n\t"
+ " movq %%mm1, %%mm3 \n\t"
+ " psrlq $32, %%mm2 \n\t" /* fold and add */
+ " psrlq $32, %%mm3 \n\t"
+ " paddw %%mm2, %%mm0 \n\t"
+ " paddw %%mm3, %%mm1 \n\t"
+ " movq %%mm0, %%mm2 \n\t"
+ " movq %%mm1, %%mm3 \n\t"
+ " psrlq $16, %%mm2 \n\t"
+ " psrlq $16, %%mm3 \n\t"
+ " paddw %%mm2, %%mm0 \n\t"
+ " paddw %%mm3, %%mm1 \n\t"
+
+ " psubusw %%mm0, %%mm1 \n\t"
+ " paddw %%mm0, %%mm1 \n\t" /* mm1 = max(mm1, mm0) */
+ " movd %%mm1, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=m" (MaxSad),
+ "+r" (Src1),
+ "+r" (Src2)
+ :
+ : "memory"
+ );
+ return MaxSad;
+}
+
+static ogg_uint32_t col_sad8x8__mmx (unsigned char *Src1, unsigned char *Src2,
+ ogg_uint32_t stride)
+{
+ ogg_uint32_t MaxSad;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm3, %%mm3 \n\t" /* zero out mm3 for unpack */
+ " pxor %%mm4, %%mm4 \n\t" /* mm4 low sum */
+ " pxor %%mm5, %%mm5 \n\t" /* mm5 high sum */
+ " pxor %%mm6, %%mm6 \n\t" /* mm6 low sum */
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 high sum */
+ " mov $4, %%edi \n\t" /* 4 rows */
+ "1: \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t" /* take 8 bytes */
+
+ " movq %%mm0, %%mm2 \n\t"
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm3, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm4 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm3, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " paddw %%mm1, %%mm5 \n\t" /* accumulate difference... */
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " add %3, %2 \n\t" /* Inc pointer into the new data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " mov $4, %%edi \n\t" /* 4 rows */
+ "2: \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t" /* take 8 bytes */
+
+ " movq %%mm0, %%mm2 \n\t"
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm3, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm6 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm3, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " paddw %%mm1, %%mm7 \n\t" /* accumulate difference... */
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " add %3, %2 \n\t" /* Inc pointer into the new data */
+
+ " dec %%edi \n\t"
+ " jnz 2b \n\t"
+
+ " psubusw %%mm6, %%mm7 \n\t"
+ " paddw %%mm6, %%mm7 \n\t" /* mm7 = max(mm7, mm6) */
+ " psubusw %%mm4, %%mm5 \n\t"
+ " paddw %%mm4, %%mm5 \n\t" /* mm5 = max(mm5, mm4) */
+ " psubusw %%mm5, %%mm7 \n\t"
+ " paddw %%mm5, %%mm7 \n\t" /* mm7 = max(mm5, mm7) */
+ " movq %%mm7, %%mm6 \n\t"
+ " psrlq $32, %%mm6 \n\t"
+ " psubusw %%mm6, %%mm7 \n\t"
+ " paddw %%mm6, %%mm7 \n\t" /* mm7 = max(mm5, mm7) */
+ " movq %%mm7, %%mm6 \n\t"
+ " psrlq $16, %%mm6 \n\t"
+ " psubusw %%mm6, %%mm7 \n\t"
+ " paddw %%mm6, %%mm7 \n\t" /* mm7 = max(mm5, mm7) */
+ " movd %%mm7, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=r" (MaxSad),
+ "+r" (Src1),
+ "+r" (Src2)
+ : "r" (stride)
+ : "memory", "edi"
+ );
+
+ return MaxSad;
+}
+
+static ogg_uint32_t sad8x8__mmx (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2)
+{
+ ogg_uint32_t DiffVal;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+ " pxor %%mm6, %%mm6 \n\t" /* zero out mm6 for unpack */
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 contains the result */
+ ".rept 8 \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+ " movq %%mm0, %%mm2 \n\t"
+
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm6, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " paddw %%mm1, %%mm7 \n\t" /* accumulate difference... */
+ " add %4, %2 \n\t" /* Inc pointer into ref data */
+ ".endr \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddw %%mm0, %%mm7 \n\t"
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $16, %%mm7 \n\t"
+ " paddw %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=m" (DiffVal),
+ "+r" (ptr1),
+ "+r" (ptr2)
+ : "r" (stride1),
+ "r" (stride2)
+ : "memory"
+ );
+
+ return DiffVal;
+}
+
+static ogg_uint32_t sad8x8_thres__mmx (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2,
+ ogg_uint32_t thres)
+{
+ return sad8x8__mmx (ptr1, stride1, ptr2, stride2);
+}
+
+static ogg_uint32_t sad8x8_xy2_thres__mmx (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride,
+ ogg_uint32_t thres)
+{
+ ogg_uint32_t DiffVal;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pcmpeqd %%mm5, %%mm5 \n\t" /* fefefefefefefefe in mm5 */
+ " paddb %%mm5, %%mm5 \n\t"
+
+ " pxor %%mm6, %%mm6 \n\t" /* zero out mm6 for unpack */
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 contains the result */
+ " mov $8, %%edi \n\t" /* 8 rows */
+ "1: \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+
+ " movq (%2), %%mm2 \n\t"
+ " movq (%3), %%mm3 \n\t" /* take average of mm2 and mm3 */
+ " movq %%mm2, %%mm1 \n\t"
+ " pand %%mm3, %%mm1 \n\t"
+ " pxor %%mm2, %%mm3 \n\t"
+ " pand %%mm5, %%mm3 \n\t"
+ " psrlq $1, %%mm3 \n\t"
+ " paddb %%mm3, %%mm1 \n\t"
+
+ " movq %%mm0, %%mm2 \n\t"
+
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm6, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " add %4, %1 \n\t" /* Inc pointer into the new data */
+ " paddw %%mm1, %%mm7 \n\t" /* accumulate difference... */
+ " add %5, %2 \n\t" /* Inc pointer into ref data */
+ " add %5, %3 \n\t" /* Inc pointer into ref data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddw %%mm0, %%mm7 \n\t"
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $16, %%mm7 \n\t"
+ " paddw %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=m" (DiffVal),
+ "+r" (SrcData),
+ "+r" (RefDataPtr1),
+ "+r" (RefDataPtr2)
+ : "m" (SrcStride),
+ "m" (RefStride)
+ : "edi", "memory"
+ );
+
+ return DiffVal;
+}
+
+static ogg_uint32_t intra8x8_err__mmx (unsigned char *DataPtr, ogg_uint32_t Stride)
+{
+ ogg_uint32_t XSum;
+ ogg_uint32_t XXSum;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm5, %%mm5 \n\t"
+ " pxor %%mm6, %%mm6 \n\t"
+ " pxor %%mm7, %%mm7 \n\t"
+ " mov $8, %%edi \n\t"
+ "1: \n\t"
+ " movq (%2), %%mm0 \n\t" /* take 8 bytes */
+ " movq %%mm0, %%mm2 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t"
+ " punpckhbw %%mm6, %%mm2 \n\t"
+
+ " paddw %%mm0, %%mm5 \n\t"
+ " paddw %%mm2, %%mm5 \n\t"
+
+ " pmaddwd %%mm0, %%mm0 \n\t"
+ " pmaddwd %%mm2, %%mm2 \n\t"
+
+ " paddd %%mm0, %%mm7 \n\t"
+ " paddd %%mm2, %%mm7 \n\t"
+
+ " add %3, %2 \n\t" /* Inc pointer into src data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $32, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $16, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movd %%mm5, %%edi \n\t"
+ " movsx %%di, %%edi \n\t"
+ " movl %%edi, %0 \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddd %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %1 \n\t"
+
+ : "=r" (XSum),
+ "=r" (XXSum),
+ "+r" (DataPtr)
+ : "r" (Stride)
+ : "edi", "memory"
+ );
+
+ /* Compute population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ) );
+}
+
+static ogg_uint32_t inter8x8_err__mmx (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr, ogg_uint32_t RefStride)
+{
+ ogg_uint32_t XSum;
+ ogg_uint32_t XXSum;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm5, %%mm5 \n\t"
+ " pxor %%mm6, %%mm6 \n\t"
+ " pxor %%mm7, %%mm7 \n\t"
+ " mov $8, %%edi \n\t"
+ "1: \n\t"
+ " movq (%2), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%3), %%mm1 \n\t"
+ " movq %%mm0, %%mm2 \n\t"
+ " movq %%mm1, %%mm3 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t"
+ " punpcklbw %%mm6, %%mm1 \n\t"
+ " punpckhbw %%mm6, %%mm2 \n\t"
+ " punpckhbw %%mm6, %%mm3 \n\t"
+
+ " psubsw %%mm1, %%mm0 \n\t"
+ " psubsw %%mm3, %%mm2 \n\t"
+
+ " paddw %%mm0, %%mm5 \n\t"
+ " paddw %%mm2, %%mm5 \n\t"
+
+ " pmaddwd %%mm0, %%mm0 \n\t"
+ " pmaddwd %%mm2, %%mm2 \n\t"
+
+ " paddd %%mm0, %%mm7 \n\t"
+ " paddd %%mm2, %%mm7 \n\t"
+
+ " add %4, %2 \n\t" /* Inc pointer into src data */
+ " add %5, %3 \n\t" /* Inc pointer into ref data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $32, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $16, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movd %%mm5, %%edi \n\t"
+ " movsx %%di, %%edi \n\t"
+ " movl %%edi, %0 \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddd %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %1 \n\t"
+
+ : "=m" (XSum),
+ "=m" (XXSum),
+ "+r" (SrcData),
+ "+r" (RefDataPtr)
+ : "m" (SrcStride),
+ "m" (RefStride)
+ : "edi", "memory"
+ );
+
+ /* Compute and return population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ));
+}
+
+static ogg_uint32_t inter8x8_err_xy2__mmx (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride)
+{
+ ogg_uint32_t XSum;
+ ogg_uint32_t XXSum;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pcmpeqd %%mm4, %%mm4 \n\t" /* fefefefefefefefe in mm4 */
+ " paddb %%mm4, %%mm4 \n\t"
+ " pxor %%mm5, %%mm5 \n\t"
+ " pxor %%mm6, %%mm6 \n\t"
+ " pxor %%mm7, %%mm7 \n\t"
+ " mov $8, %%edi \n\t"
+ "1: \n\t"
+ " movq (%2), %%mm0 \n\t" /* take 8 bytes */
+
+ " movq (%3), %%mm2 \n\t"
+ " movq (%4), %%mm3 \n\t" /* take average of mm2 and mm3 */
+ " movq %%mm2, %%mm1 \n\t"
+ " pand %%mm3, %%mm1 \n\t"
+ " pxor %%mm2, %%mm3 \n\t"
+ " pand %%mm4, %%mm3 \n\t"
+ " psrlq $1, %%mm3 \n\t"
+ " paddb %%mm3, %%mm1 \n\t"
+
+ " movq %%mm0, %%mm2 \n\t"
+ " movq %%mm1, %%mm3 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t"
+ " punpcklbw %%mm6, %%mm1 \n\t"
+ " punpckhbw %%mm6, %%mm2 \n\t"
+ " punpckhbw %%mm6, %%mm3 \n\t"
+
+ " psubsw %%mm1, %%mm0 \n\t"
+ " psubsw %%mm3, %%mm2 \n\t"
+
+ " paddw %%mm0, %%mm5 \n\t"
+ " paddw %%mm2, %%mm5 \n\t"
+
+ " pmaddwd %%mm0, %%mm0 \n\t"
+ " pmaddwd %%mm2, %%mm2 \n\t"
+
+ " paddd %%mm0, %%mm7 \n\t"
+ " paddd %%mm2, %%mm7 \n\t"
+
+ " add %5, %2 \n\t" /* Inc pointer into src data */
+ " add %6, %3 \n\t" /* Inc pointer into ref data */
+ " add %6, %4 \n\t" /* Inc pointer into ref data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $32, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $16, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movd %%mm5, %%edi \n\t"
+ " movsx %%di, %%edi \n\t"
+ " movl %%edi, %0 \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddd %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %1 \n\t"
+
+ : "=m" (XSum),
+ "=m" (XXSum),
+ "+r" (SrcData),
+ "+r" (RefDataPtr1),
+ "+r" (RefDataPtr2)
+ : "m" (SrcStride),
+ "m" (RefStride)
+ : "edi", "memory"
+ );
+
+ /* Compute and return population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ));
+}
+
+static void restore_fpu (void)
+{
+ __asm__ __volatile__ (
+ " emms \n\t"
+ );
+}
+
+void dsp_i386_mmx_init(DspFunctions *funcs)
+{
+ funcs->restore_fpu = restore_fpu;
+ funcs->sub8x8 = sub8x8__mmx;
+ funcs->sub8x8_128 = sub8x8_128__mmx;
+ funcs->sub8x8avg2 = sub8x8avg2__mmx;
+ funcs->row_sad8 = row_sad8__mmx;
+ funcs->col_sad8x8 = col_sad8x8__mmx;
+ funcs->sad8x8 = sad8x8__mmx;
+ funcs->sad8x8_thres = sad8x8_thres__mmx;
+ funcs->sad8x8_xy2_thres = sad8x8_xy2_thres__mmx;
+ funcs->intra8x8_err = intra8x8_err__mmx;
+ funcs->inter8x8_err = inter8x8_err__mmx;
+ funcs->inter8x8_err_xy2 = inter8x8_err_xy2__mmx;
+}
+
Index: lib/i386/recon_mmx.c
===================================================================
--- lib/i386/recon_mmx.c (revision 0)
+++ lib/i386/recon_mmx.c (revision 0)
@@ -0,0 +1,185 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: reconstruct.c,v 1.6 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include "encoder_internal.h"
+
+static const __attribute__ ((aligned(8))) ogg_int64_t V128 = 0x8080808080808080LL;
+
+#if defined(__MINGW32__) || defined(__CYGWIN__) || \
+ defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
+# define M(a) "_" #a
+#else
+# define M(a) #a
+#endif
+
+static void copy8x8__mmx (unsigned char *src,
+ unsigned char *dest,
+ unsigned int stride)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " lea (%2, %2, 2), %%edi \n\t"
+
+ " movq (%1), %%mm0 \n\t"
+ " movq (%1, %2), %%mm1 \n\t"
+ " movq (%1, %2, 2), %%mm2 \n\t"
+ " movq (%1, %%edi), %%mm3 \n\t"
+
+ " lea (%1, %2, 4), %1 \n\t"
+
+ " movq %%mm0, (%0) \n\t"
+ " movq %%mm1, (%0, %2) \n\t"
+ " movq %%mm2, (%0, %2, 2) \n\t"
+ " movq %%mm3, (%0, %%edi) \n\t"
+
+ " lea (%0, %2, 4), %0 \n\t"
+
+ " movq (%1), %%mm0 \n\t"
+ " movq (%1, %2), %%mm1 \n\t"
+ " movq (%1, %2, 2), %%mm2 \n\t"
+ " movq (%1, %%edi), %%mm3 \n\t"
+
+ " movq %%mm0, (%0) \n\t"
+ " movq %%mm1, (%0, %2) \n\t"
+ " movq %%mm2, (%0, %2, 2) \n\t"
+ " movq %%mm3, (%0, %%edi) \n\t"
+ : "+a" (dest)
+ : "c" (src),
+ "d" (stride)
+ : "memory", "edi"
+ );
+}
+
+static void recon_intra8x8__mmx (unsigned char *ReconPtr, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " movq "M(V128)", %%mm0 \n\t" /* Set mm0 to 0x8080808080808080 */
+
+ " lea 128(%1), %%edi \n\t" /* Endpoint in input buffer */
+ "1: \n\t"
+ " movq (%1), %%mm2 \n\t" /* First four input values */
+
+ " packsswb 8(%1), %%mm2 \n\t" /* pack with next(high) four values */
+ " por %%mm0, %%mm0 \n\t"
+ " pxor %%mm0, %%mm2 \n\t" /* Convert result to unsigned (same as add 128) */
+ " lea 16(%1), %1 \n\t" /* Step source buffer */
+ " cmp %%edi, %1 \n\t" /* are we done */
+
+ " movq %%mm2, (%0) \n\t" /* store results */
+
+ " lea (%0, %2), %0 \n\t" /* Step output buffer */
+ " jc 1b \n\t" /* Loop back if we are not done */
+ : "+r" (ReconPtr)
+ : "r" (ChangePtr),
+ "r" (LineStep)
+ : "memory", "edi"
+ );
+}
+
+static void recon_inter8x8__mmx (unsigned char *ReconPtr, unsigned char *RefPtr,
+ ogg_int16_t *ChangePtr, ogg_uint32_t LineStep)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm0, %%mm0 \n\t"
+ " lea 128(%1), %%edi \n\t"
+
+ "1: \n\t"
+ " movq (%2), %%mm2 \n\t" /* (+3 misaligned) 8 reference pixels */
+
+ " movq (%1), %%mm4 \n\t" /* first 4 changes */
+ " movq %%mm2, %%mm3 \n\t"
+ " movq 8(%1), %%mm5 \n\t" /* last 4 changes */
+ " punpcklbw %%mm0, %%mm2 \n\t" /* turn first 4 refs into positive 16-bit #s */
+ " paddsw %%mm4, %%mm2 \n\t" /* add in first 4 changes */
+ " punpckhbw %%mm0, %%mm3 \n\t" /* turn last 4 refs into positive 16-bit #s */
+ " paddsw %%mm5, %%mm3 \n\t" /* add in last 4 changes */
+ " add %3, %2 \n\t" /* next row of reference pixels */
+ " packuswb %%mm3, %%mm2 \n\t" /* pack result to unsigned 8-bit values */
+ " lea 16(%1), %1 \n\t" /* next row of changes */
+ " cmp %%edi, %1 \n\t" /* are we done? */
+
+ " movq %%mm2, (%0) \n\t" /* store result */
+
+ " lea (%0, %3), %0 \n\t" /* next row of output */
+ " jc 1b \n\t"
+ : "+r" (ReconPtr)
+ : "r" (ChangePtr),
+ "r" (RefPtr),
+ "r" (LineStep)
+ : "memory", "edi"
+ );
+}
+
+static void recon_inter8x8_half__mmx (unsigned char *ReconPtr, unsigned char *RefPtr1,
+ unsigned char *RefPtr2, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep)
+{
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm0, %%mm0 \n\t"
+ " lea 128(%1), %%edi \n\t"
+
+ "1: \n\t"
+ " movq (%2), %%mm2 \n\t" /* (+3 misaligned) 8 reference pixels */
+ " movq (%3), %%mm4 \n\t" /* (+3 misaligned) 8 reference pixels */
+
+ " movq %%mm2, %%mm3 \n\t"
+ " punpcklbw %%mm0, %%mm2 \n\t" /* mm2 = start ref1 as positive 16-bit #s */
+ " movq %%mm4, %%mm5 \n\t"
+ " movq (%1), %%mm6 \n\t" /* first 4 changes */
+ " punpckhbw %%mm0, %%mm3 \n\t" /* mm3 = end ref1 as positive 16-bit #s */
+ " movq 8(%1), %%mm7 \n\t" /* last 4 changes */
+ " punpcklbw %%mm0, %%mm4 \n\t" /* mm4 = start ref2 as positive 16-bit #s */
+ " punpckhbw %%mm0, %%mm5 \n\t" /* mm5 = end ref2 as positive 16-bit #s */
+ " paddw %%mm4, %%mm2 \n\t" /* mm2 = start (ref1 + ref2) */
+ " paddw %%mm5, %%mm3 \n\t" /* mm3 = end (ref1 + ref2) */
+ " psrlw $1, %%mm2 \n\t" /* mm2 = start (ref1 + ref2)/2 */
+ " psrlw $1, %%mm3 \n\t" /* mm3 = end (ref1 + ref2)/2 */
+ " paddw %%mm6, %%mm2 \n\t" /* add changes to start */
+ " paddw %%mm7, %%mm3 \n\t" /* add changes to end */
+ " lea 16(%1), %1 \n\t" /* next row of changes */
+ " packuswb %%mm3, %%mm2 \n\t" /* pack start|end to unsigned 8-bit */
+ " add %4, %2 \n\t" /* next row of reference pixels */
+ " add %4, %3 \n\t" /* next row of reference pixels */
+ " movq %%mm2, (%0) \n\t" /* store result */
+ " add %4, %0 \n\t" /* next row of output */
+ " cmp %%edi, %1 \n\t" /* are we done? */
+ " jc 1b \n\t"
+ : "+r" (ReconPtr)
+ : "r" (ChangePtr),
+ "r" (RefPtr1),
+ "r" (RefPtr2),
+ "m" (LineStep)
+ : "memory", "edi"
+ );
+}
+
+void dsp_i386_mmx_recon_init(DspFunctions *funcs)
+{
+ funcs->copy8x8 = copy8x8__mmx;
+ funcs->recon_intra8x8 = recon_intra8x8__mmx;
+ funcs->recon_inter8x8 = recon_inter8x8__mmx;
+ funcs->recon_inter8x8_half = recon_inter8x8_half__mmx;
+}
+
Index: lib/i386/dsp_mmxext.c
===================================================================
--- lib/i386/dsp_mmxext.c (revision 0)
+++ lib/i386/dsp_mmxext.c (revision 0)
@@ -0,0 +1,316 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include "dsp.h"
+
+static ogg_uint32_t sad8x8__mmxext (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2)
+{
+ ogg_uint32_t DiffVal;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 contains the result */
+
+ ".rept 7 \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+ " psadbw %%mm1, %%mm0 \n\t"
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " add %4, %2 \n\t" /* Inc pointer into ref data */
+ ".endr \n\t"
+
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+ " psadbw %%mm1, %%mm0 \n\t"
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " movd %%mm7, %0 \n\t"
+
+ : "=r" (DiffVal),
+ "+r" (ptr1),
+ "+r" (ptr2)
+ : "r" (stride1),
+ "r" (stride2)
+ : "memory"
+ );
+
+ return DiffVal;
+}
+
+static ogg_uint32_t sad8x8_thres__mmxext (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2,
+ ogg_uint32_t thres)
+{
+ ogg_uint32_t DiffVal;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 contains the result */
+
+ ".rept 8 \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+ " psadbw %%mm1, %%mm0 \n\t"
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " add %4, %2 \n\t" /* Inc pointer into ref data */
+ ".endr \n\t"
+
+ " movd %%mm7, %0 \n\t"
+
+ : "=r" (DiffVal),
+ "+r" (ptr1),
+ "+r" (ptr2)
+ : "r" (stride1),
+ "r" (stride2)
+ : "memory"
+ );
+
+ return DiffVal;
+}
+
+static ogg_uint32_t sad8x8_xy2_thres__mmxext (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride,
+ ogg_uint32_t thres)
+{
+ ogg_uint32_t DiffVal;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 contains the result */
+ ".rept 8 \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t"
+ " movq (%3), %%mm2 \n\t"
+ " pavgb %%mm2, %%mm1 \n\t"
+ " psadbw %%mm1, %%mm0 \n\t"
+
+ " add %4, %1 \n\t" /* Inc pointer into the new data */
+ " paddw %%mm0, %%mm7 \n\t" /* accumulate difference... */
+ " add %5, %2 \n\t" /* Inc pointer into ref data */
+ " add %5, %3 \n\t" /* Inc pointer into ref data */
+ ".endr \n\t"
+
+ " movd %%mm7, %0 \n\t"
+ : "=m" (DiffVal),
+ "+r" (SrcData),
+ "+r" (RefDataPtr1),
+ "+r" (RefDataPtr2)
+ : "m" (SrcStride),
+ "m" (RefStride)
+ : "memory"
+ );
+
+ return DiffVal;
+}
+
+static ogg_uint32_t row_sad8__mmxext (unsigned char *Src1, unsigned char *Src2)
+{
+ ogg_uint32_t MaxSad;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " movd (%1), %%mm0 \n\t"
+ " movd (%2), %%mm1 \n\t"
+ " psadbw %%mm0, %%mm1 \n\t"
+ " movd 4(%1), %%mm2 \n\t"
+ " movd 4(%2), %%mm3 \n\t"
+ " psadbw %%mm2, %%mm3 \n\t"
+
+ " pmaxsw %%mm1, %%mm3 \n\t"
+ " movd %%mm3, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=m" (MaxSad),
+ "+r" (Src1),
+ "+r" (Src2)
+ :
+ : "memory"
+ );
+
+ return MaxSad;
+}
+
+static ogg_uint32_t col_sad8x8__mmxext (unsigned char *Src1, unsigned char *Src2,
+ ogg_uint32_t stride)
+{
+ ogg_uint32_t MaxSad;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm3, %%mm3 \n\t" /* zero out mm3 for unpack */
+ " pxor %%mm4, %%mm4 \n\t" /* mm4 low sum */
+ " pxor %%mm5, %%mm5 \n\t" /* mm5 high sum */
+ " pxor %%mm6, %%mm6 \n\t" /* mm6 low sum */
+ " pxor %%mm7, %%mm7 \n\t" /* mm7 high sum */
+ " mov $4, %%edi \n\t" /* 4 rows */
+ "1: \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t" /* take 8 bytes */
+
+ " movq %%mm0, %%mm2 \n\t"
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm3, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm4 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm3, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " paddw %%mm1, %%mm5 \n\t" /* accumulate difference... */
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " add %3, %2 \n\t" /* Inc pointer into the new data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " mov $4, %%edi \n\t" /* 4 rows */
+ "2: \n\t"
+ " movq (%1), %%mm0 \n\t" /* take 8 bytes */
+ " movq (%2), %%mm1 \n\t" /* take 8 bytes */
+
+ " movq %%mm0, %%mm2 \n\t"
+ " psubusb %%mm1, %%mm0 \n\t" /* A - B */
+ " psubusb %%mm2, %%mm1 \n\t" /* B - A */
+ " por %%mm1, %%mm0 \n\t" /* and or gives abs difference */
+ " movq %%mm0, %%mm1 \n\t"
+
+ " punpcklbw %%mm3, %%mm0 \n\t" /* unpack to higher precision for accumulation */
+ " paddw %%mm0, %%mm6 \n\t" /* accumulate difference... */
+ " punpckhbw %%mm3, %%mm1 \n\t" /* unpack high four bytes to higher precision */
+ " paddw %%mm1, %%mm7 \n\t" /* accumulate difference... */
+ " add %3, %1 \n\t" /* Inc pointer into the new data */
+ " add %3, %2 \n\t" /* Inc pointer into the new data */
+
+ " dec %%edi \n\t"
+ " jnz 2b \n\t"
+
+ " pmaxsw %%mm6, %%mm7 \n\t"
+ " pmaxsw %%mm4, %%mm5 \n\t"
+ " pmaxsw %%mm5, %%mm7 \n\t"
+ " movq %%mm7, %%mm6 \n\t"
+ " psrlq $32, %%mm6 \n\t"
+ " pmaxsw %%mm6, %%mm7 \n\t"
+ " movq %%mm7, %%mm6 \n\t"
+ " psrlq $16, %%mm6 \n\t"
+ " pmaxsw %%mm6, %%mm7 \n\t"
+ " movd %%mm7, %0 \n\t"
+ " andl $0xffff, %0 \n\t"
+
+ : "=r" (MaxSad),
+ "+r" (Src1),
+ "+r" (Src2)
+ : "r" (stride)
+ : "memory", "edi"
+ );
+
+ return MaxSad;
+}
+
+static ogg_uint32_t inter8x8_err_xy2__mmxext (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride)
+{
+ ogg_uint32_t XSum;
+ ogg_uint32_t XXSum;
+
+ __asm__ __volatile__ (
+ " .balign 16 \n\t"
+
+ " pxor %%mm4, %%mm4 \n\t"
+ " pxor %%mm5, %%mm5 \n\t"
+ " pxor %%mm6, %%mm6 \n\t"
+ " pxor %%mm7, %%mm7 \n\t"
+ " mov $8, %%edi \n\t"
+ "1: \n\t"
+ " movq (%2), %%mm0 \n\t" /* take 8 bytes */
+
+ " movq (%3), %%mm2 \n\t"
+ " movq (%4), %%mm1 \n\t" /* take average of mm2 and mm1 */
+ " pavgb %%mm2, %%mm1 \n\t"
+
+ " movq %%mm0, %%mm2 \n\t"
+ " movq %%mm1, %%mm3 \n\t"
+
+ " punpcklbw %%mm6, %%mm0 \n\t"
+ " punpcklbw %%mm4, %%mm1 \n\t"
+ " punpckhbw %%mm6, %%mm2 \n\t"
+ " punpckhbw %%mm4, %%mm3 \n\t"
+
+ " psubsw %%mm1, %%mm0 \n\t"
+ " psubsw %%mm3, %%mm2 \n\t"
+
+ " paddw %%mm0, %%mm5 \n\t"
+ " paddw %%mm2, %%mm5 \n\t"
+
+ " pmaddwd %%mm0, %%mm0 \n\t"
+ " pmaddwd %%mm2, %%mm2 \n\t"
+
+ " paddd %%mm0, %%mm7 \n\t"
+ " paddd %%mm2, %%mm7 \n\t"
+
+ " add %5, %2 \n\t" /* Inc pointer into src data */
+ " add %6, %3 \n\t" /* Inc pointer into ref data */
+ " add %6, %4 \n\t" /* Inc pointer into ref data */
+
+ " dec %%edi \n\t"
+ " jnz 1b \n\t"
+
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $32, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movq %%mm5, %%mm0 \n\t"
+ " psrlq $16, %%mm5 \n\t"
+ " paddw %%mm0, %%mm5 \n\t"
+ " movd %%mm5, %%edi \n\t"
+ " movsx %%di, %%edi \n\t"
+ " movl %%edi, %0 \n\t"
+
+ " movq %%mm7, %%mm0 \n\t"
+ " psrlq $32, %%mm7 \n\t"
+ " paddd %%mm0, %%mm7 \n\t"
+ " movd %%mm7, %1 \n\t"
+
+ : "=m" (XSum),
+ "=m" (XXSum),
+ "+r" (SrcData),
+ "+r" (RefDataPtr1),
+ "+r" (RefDataPtr2)
+ : "m" (SrcStride),
+ "m" (RefStride)
+ : "edi", "memory"
+ );
+
+ /* Compute and return population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ));
+}
+
+void dsp_i386_mmxext_init(DspFunctions *funcs)
+{
+ funcs->row_sad8 = row_sad8__mmxext;
+ funcs->col_sad8x8 = col_sad8x8__mmxext;
+ funcs->sad8x8 = sad8x8__mmxext;
+ funcs->sad8x8_thres = sad8x8_thres__mmxext;
+ funcs->sad8x8_xy2_thres = sad8x8_xy2_thres__mmxext;
+ funcs->inter8x8_err_xy2 = inter8x8_err_xy2__mmxext;
+}
+
Index: lib/dct.c
===================================================================
--- lib/dct.c (revision 7621)
+++ lib/dct.c (working copy)
@@ -16,6 +16,7 @@
********************************************************************/
#include "encoder_internal.h"
+#include "cpu.h"
static ogg_int32_t xC1S7 = 64277;
static ogg_int32_t xC2S6 = 60547;
@@ -28,7 +29,7 @@
#define SIGNBITDUPPED(X) ((signed )(((X) & 0x80000000)) >> 31)
#define DOROUND(X) ( (SIGNBITDUPPED(X) & (0xffff)) + (X) )
-void fdct_short ( ogg_int16_t * InputData, ogg_int16_t * OutputData ){
+static void fdct_short__c ( ogg_int16_t * InputData, ogg_int16_t * OutputData ){
int loop;
ogg_int32_t is07, is12, is34, is56;
@@ -251,3 +252,12 @@
op ++;
}
}
+
+void dsp_dct_init (DspFunctions *funcs)
+{
+ funcs->fdct_short = fdct_short__c;
+ if (cpu_flags & CPU_X86_MMX) {
+ dsp_i386_mmx_fdct_init(&dsp_funcs);
+ }
+}
+
Index: lib/mcomp.c
===================================================================
--- lib/mcomp.c (revision 7621)
+++ lib/mcomp.c (working copy)
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include "dsp.h"
#include "encoder_internal.h"
/* Initialises motion compentsation. */
@@ -100,164 +101,25 @@
unsigned char * RefDataPtr1,
unsigned char * RefDataPtr2,
ogg_uint32_t PixelsPerLine ) {
- ogg_uint32_t i;
- ogg_int32_t XSum=0;
- ogg_int32_t XXSum=0;
ogg_int32_t DiffVal;
- ogg_int32_t AbsRefOffset = abs((int)(RefDataPtr1 - RefDataPtr2));
+ ogg_int32_t RefOffset = (int)(RefDataPtr1 - RefDataPtr2);
+ ogg_uint32_t RefPixelsPerLine = PixelsPerLine + STRIDE_EXTRA;
/* Mode of interpolation chosen based upon on the offset of the
second reference pointer */
- if ( AbsRefOffset == 0 ) {
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ) {
- DiffVal = ((int)NewDataPtr[0]) - (int)RefDataPtr1[0];
- XSum += DiffVal;
-
- /* negative array indexes are strictly forbidden by ANSI C and C99 */
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[1]) - (int)RefDataPtr1[1];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[2]) - (int)RefDataPtr1[2];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[3]) - (int)RefDataPtr1[3];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[4]) - (int)RefDataPtr1[4];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[5]) - (int)RefDataPtr1[5];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[6]) - (int)RefDataPtr1[6];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[7]) - (int)RefDataPtr1[7];
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- /* Step to next row of block. */
- NewDataPtr += PixelsPerLine;
- RefDataPtr1 += STRIDE_EXTRA + PixelsPerLine;
- }
-
+ if ( RefOffset == 0 ) {
+ DiffVal = dsp_static_inter8x8_err (NewDataPtr, PixelsPerLine,
+ RefDataPtr1, RefPixelsPerLine);
}else{
-
- /* Simple two reference interpolation */
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ) {
- DiffVal = ((int)NewDataPtr[0]) -
- (((int)RefDataPtr1[0] + (int)RefDataPtr2[0]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[1]) -
- (((int)RefDataPtr1[1] + (int)RefDataPtr2[1]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[2]) -
- (((int)RefDataPtr1[2] + (int)RefDataPtr2[2]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[3]) -
- (((int)RefDataPtr1[3] + (int)RefDataPtr2[3]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[4]) -
- (((int)RefDataPtr1[4] + (int)RefDataPtr2[4]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[5]) -
- (((int)RefDataPtr1[5] + (int)RefDataPtr2[5]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[6]) -
- (((int)RefDataPtr1[6] + (int)RefDataPtr2[6]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- DiffVal = ((int)NewDataPtr[7]) -
- (((int)RefDataPtr1[7] + (int)RefDataPtr2[7]) / 2);
- XSum += DiffVal;
- XXSum += DiffVal*DiffVal;
-
- /* Step to next row of block. */
- NewDataPtr += PixelsPerLine;
- RefDataPtr1 += STRIDE_EXTRA+PixelsPerLine;
- RefDataPtr2 += STRIDE_EXTRA+PixelsPerLine;
- }
+ DiffVal = dsp_static_inter8x8_err_xy2 (NewDataPtr, PixelsPerLine,
+ RefDataPtr1,
+ RefDataPtr2, RefPixelsPerLine);
}
/* Compute and return population variance as mis-match metric. */
- return (( (XXSum<<6) - XSum*XSum ));
-}
-
-static ogg_uint32_t GetSumAbsDiffs (unsigned char * NewDataPtr,
- unsigned char * RefDataPtr,
- ogg_uint32_t PixelsPerLine,
- ogg_uint32_t ErrorSoFar) {
- ogg_uint32_t i;
- ogg_uint32_t DiffVal = ErrorSoFar;
-
- /* Decide on standard or MMX implementation */
- for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
- DiffVal += abs( ((int)NewDataPtr[0]) - ((int)RefDataPtr[0]) );
- DiffVal += abs( ((int)NewDataPtr[1]) - ((int)RefDataPtr[1]) );
- DiffVal += abs( ((int)NewDataPtr[2]) - ((int)RefDataPtr[2]) );
- DiffVal += abs( ((int)NewDataPtr[3]) - ((int)RefDataPtr[3]) );
- DiffVal += abs( ((int)NewDataPtr[4]) - ((int)RefDataPtr[4]) );
- DiffVal += abs( ((int)NewDataPtr[5]) - ((int)RefDataPtr[5]) );
- DiffVal += abs( ((int)NewDataPtr[6]) - ((int)RefDataPtr[6]) );
- DiffVal += abs( ((int)NewDataPtr[7]) - ((int)RefDataPtr[7]) );
-
- /* Step to next row of block. */
- NewDataPtr += PixelsPerLine;
- RefDataPtr += STRIDE_EXTRA+PixelsPerLine;
- }
-
return DiffVal;
}
-static ogg_uint32_t GetNextSumAbsDiffs (unsigned char * NewDataPtr,
- unsigned char * RefDataPtr,
- ogg_uint32_t PixelsPerLine,
- ogg_uint32_t ErrorSoFar,
- ogg_uint32_t BestSoFar ) {
- ogg_uint32_t i;
- ogg_uint32_t DiffVal = ErrorSoFar;
-
- for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
- DiffVal += abs( ((int)NewDataPtr[0]) - ((int)RefDataPtr[0]) );
- DiffVal += abs( ((int)NewDataPtr[1]) - ((int)RefDataPtr[1]) );
- DiffVal += abs( ((int)NewDataPtr[2]) - ((int)RefDataPtr[2]) );
- DiffVal += abs( ((int)NewDataPtr[3]) - ((int)RefDataPtr[3]) );
- DiffVal += abs( ((int)NewDataPtr[4]) - ((int)RefDataPtr[4]) );
- DiffVal += abs( ((int)NewDataPtr[5]) - ((int)RefDataPtr[5]) );
- DiffVal += abs( ((int)NewDataPtr[6]) - ((int)RefDataPtr[6]) );
- DiffVal += abs( ((int)NewDataPtr[7]) - ((int)RefDataPtr[7]) );
-
- if ( DiffVal > BestSoFar )break;
-
- /* Step to next row of block. */
- NewDataPtr += PixelsPerLine;
- RefDataPtr += STRIDE_EXTRA+PixelsPerLine;
- }
-
- return DiffVal;
-}
-
static ogg_uint32_t GetHalfPixelSumAbsDiffs (unsigned char * SrcData,
unsigned char * RefDataPtr1,
unsigned char * RefDataPtr2,
@@ -265,119 +127,61 @@
ogg_uint32_t ErrorSoFar,
ogg_uint32_t BestSoFar ) {
- ogg_uint32_t i;
ogg_uint32_t DiffVal = ErrorSoFar;
ogg_int32_t RefOffset = (int)(RefDataPtr1 - RefDataPtr2);
ogg_uint32_t RefPixelsPerLine = PixelsPerLine + STRIDE_EXTRA;
if ( RefOffset == 0 ) {
/* Simple case as for non 0.5 pixel */
- DiffVal += GetSumAbsDiffs( SrcData, RefDataPtr1, PixelsPerLine,
- ErrorSoFar);
+ DiffVal += dsp_static_sad8x8 (SrcData, PixelsPerLine,
+ RefDataPtr1, RefPixelsPerLine);
} else {
- for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
- DiffVal += abs( ((int)SrcData[0]) - (((int)RefDataPtr1[0] +
- (int)RefDataPtr2[0]) / 2) );
- DiffVal += abs( ((int)SrcData[1]) - (((int)RefDataPtr1[1] +
- (int)RefDataPtr2[1]) / 2) );
- DiffVal += abs( ((int)SrcData[2]) - (((int)RefDataPtr1[2] +
- (int)RefDataPtr2[2]) / 2) );
- DiffVal += abs( ((int)SrcData[3]) - (((int)RefDataPtr1[3] +
- (int)RefDataPtr2[3]) / 2) );
- DiffVal += abs( ((int)SrcData[4]) - (((int)RefDataPtr1[4] +
- (int)RefDataPtr2[4]) / 2) );
- DiffVal += abs( ((int)SrcData[5]) - (((int)RefDataPtr1[5] +
- (int)RefDataPtr2[5]) / 2) );
- DiffVal += abs( ((int)SrcData[6]) - (((int)RefDataPtr1[6] +
- (int)RefDataPtr2[6]) / 2) );
- DiffVal += abs( ((int)SrcData[7]) - (((int)RefDataPtr1[7] +
- (int)RefDataPtr2[7]) / 2) );
-
- if ( DiffVal > BestSoFar ) break;
-
- /* Step to next row of block. */
- SrcData += PixelsPerLine;
- RefDataPtr1 += RefPixelsPerLine;
- RefDataPtr2 += RefPixelsPerLine;
- }
+ DiffVal += dsp_static_sad8x8_xy2_thres (SrcData, PixelsPerLine,
+ RefDataPtr1,
+ RefDataPtr2, RefPixelsPerLine, BestSoFar);
}
return DiffVal;
}
-static ogg_uint32_t GetIntraError (unsigned char * DataPtr,
- ogg_uint32_t PixelsPerLine ) {
- ogg_uint32_t i;
- ogg_uint32_t XSum=0;
- ogg_uint32_t XXSum=0;
- unsigned char *DiffPtr;
-
- /* Loop expanded out for speed. */
- DiffPtr = DataPtr;
-
- for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ ) {
-
- /* Examine alternate pixel locations. */
- XSum += DiffPtr[0];
- XXSum += DiffPtr[0]*DiffPtr[0];
- XSum += DiffPtr[1];
- XXSum += DiffPtr[1]*DiffPtr[1];
- XSum += DiffPtr[2];
- XXSum += DiffPtr[2]*DiffPtr[2];
- XSum += DiffPtr[3];
- XXSum += DiffPtr[3]*DiffPtr[3];
- XSum += DiffPtr[4];
- XXSum += DiffPtr[4]*DiffPtr[4];
- XSum += DiffPtr[5];
- XXSum += DiffPtr[5]*DiffPtr[5];
- XSum += DiffPtr[6];
- XXSum += DiffPtr[6]*DiffPtr[6];
- XSum += DiffPtr[7];
- XXSum += DiffPtr[7]*DiffPtr[7];
-
- /* Step to next row of block. */
- DiffPtr += PixelsPerLine;
- }
-
- /* Compute population variance as mis-match metric. */
- return (( (XXSum<<6) - XSum*XSum ) );
-}
-
ogg_uint32_t GetMBIntraError (CP_INSTANCE *cpi, ogg_uint32_t FragIndex,
ogg_uint32_t PixelsPerLine ) {
ogg_uint32_t LocalFragIndex = FragIndex;
ogg_uint32_t IntraError = 0;
+ dsp_static_save_fpu ();
+
/* Add together the intra errors for those blocks in the macro block
that are coded (Y only) */
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- GetIntraError(&cpi->
+ dsp_static_intra8x8_err (&cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]],
- PixelsPerLine );
+ PixelsPerLine);
-
LocalFragIndex++;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- GetIntraError(&cpi->
+ dsp_static_intra8x8_err (&cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]],
- PixelsPerLine );
+ PixelsPerLine);
LocalFragIndex = FragIndex + cpi->pb.HFragments;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- GetIntraError(&cpi->
+ dsp_static_intra8x8_err (&cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]],
- PixelsPerLine );
+ PixelsPerLine);
LocalFragIndex++;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- GetIntraError(&cpi->
+ dsp_static_intra8x8_err (&cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]],
- PixelsPerLine );
+ PixelsPerLine);
+ dsp_static_restore_fpu ();
+
return IntraError;
}
@@ -400,6 +204,8 @@
unsigned char * SrcPtr1;
unsigned char * RefPtr1;
+ dsp_static_save_fpu ();
+
/* Work out pixel offset into source buffer. */
PixelIndex = cpi->pb.pixel_index_table[LocalFragIndex];
@@ -462,6 +268,9 @@
InterError += GetInterErr( SrcPtr1, RefPtr1,
&RefPtr1[RefPtr2Offset], PixelsPerLine );
}
+
+ dsp_static_restore_fpu ();
+
return InterError;
}
@@ -496,6 +305,8 @@
unsigned char * RefDataPtr1;
unsigned char * RefDataPtr2;
+ dsp_static_save_fpu ();
+
/* Note which of the four blocks in the macro block are to be
included in the search. */
MBlockDispFrags[0] =
@@ -518,20 +329,20 @@
/* Check the 0,0 candidate. */
if ( MBlockDispFrags[0] ) {
- Error = GetSumAbsDiffs( SrcPtr[0], RefPtr,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[0], PixelsPerLine, RefPtr,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[1] ) {
- Error = GetSumAbsDiffs( SrcPtr[1], RefPtr + 8,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[1], PixelsPerLine, RefPtr + 8,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[2] ) {
- Error = GetSumAbsDiffs( SrcPtr[2], RefPtr + RefRow2Offset,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[2], PixelsPerLine, RefPtr + RefRow2Offset,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[3] ) {
- Error = GetSumAbsDiffs( SrcPtr[3], RefPtr + RefRow2Offset + 8,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[3], PixelsPerLine, RefPtr + RefRow2Offset + 8,
+ PixelsPerLine + STRIDE_EXTRA);
}
/* Set starting values to results of 0, 0 vector. */
@@ -554,24 +365,23 @@
/* Get the score for the current offset */
if ( MBlockDispFrags[0] ) {
- Error = GetSumAbsDiffs( SrcPtr[0], CandidateBlockPtr,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[0], PixelsPerLine, CandidateBlockPtr,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[1] && (Error < MinError) ) {
- Error = GetNextSumAbsDiffs( SrcPtr[1], CandidateBlockPtr + 8,
- PixelsPerLine, Error, MinError );
+ Error += dsp_static_sad8x8_thres (SrcPtr[1], PixelsPerLine, CandidateBlockPtr + 8,
+ PixelsPerLine + STRIDE_EXTRA, MinError);
}
if ( MBlockDispFrags[2] && (Error < MinError) ) {
- Error = GetNextSumAbsDiffs( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
- PixelsPerLine, Error, MinError );
+ Error += dsp_static_sad8x8_thres (SrcPtr[2], PixelsPerLine, CandidateBlockPtr + RefRow2Offset,
+ PixelsPerLine + STRIDE_EXTRA, MinError);
}
if ( MBlockDispFrags[3] && (Error < MinError) ) {
- Error = GetNextSumAbsDiffs( SrcPtr[3],
- CandidateBlockPtr + RefRow2Offset + 8,
- PixelsPerLine, Error, MinError );
+ Error += dsp_static_sad8x8_thres (SrcPtr[3], PixelsPerLine, CandidateBlockPtr + RefRow2Offset + 8,
+ PixelsPerLine + STRIDE_EXTRA, MinError);
}
if ( Error < MinError ) {
@@ -652,6 +462,8 @@
InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr,
FragIndex, MV->x, MV->y, PixelsPerLine );
+ dsp_static_restore_fpu ();
+
/* Return score of best matching block. */
return InterMVError;
}
@@ -684,6 +496,8 @@
unsigned char * RefDataPtr1;
unsigned char * RefDataPtr2;
+ dsp_static_save_fpu ();
+
/* Note which of the four blocks in the macro block are to be
included in the search. */
MBlockDispFrags[0] = cpi->
@@ -717,20 +531,20 @@
/* Summ errors for each block. */
if ( MBlockDispFrags[0] ) {
- Error = GetSumAbsDiffs( SrcPtr[0], CandidateBlockPtr,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[0], PixelsPerLine, CandidateBlockPtr,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[1] ){
- Error = GetSumAbsDiffs( SrcPtr[1], CandidateBlockPtr + 8,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[1], PixelsPerLine, CandidateBlockPtr + 8,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[2] ){
- Error = GetSumAbsDiffs( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[2], PixelsPerLine, CandidateBlockPtr + RefRow2Offset,
+ PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[3] ){
- Error = GetSumAbsDiffs( SrcPtr[3], CandidateBlockPtr + RefRow2Offset + 8,
- PixelsPerLine, Error);
+ Error += dsp_static_sad8x8 (SrcPtr[3], PixelsPerLine, CandidateBlockPtr + RefRow2Offset + 8,
+ PixelsPerLine + STRIDE_EXTRA);
}
/* Was this the best so far */
@@ -808,6 +622,8 @@
InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr,
FragIndex, MV->x, MV->y, PixelsPerLine );
+ dsp_static_restore_fpu ();
+
/* Return score of best matching block. */
return InterMVError;
}
@@ -850,8 +666,8 @@
for ( j = 0; j < (ogg_int32_t)MAX_MV_EXTENT; j++ ){
/* Get the block error score. */
- Error = GetSumAbsDiffs( SrcPtr, CandidateBlockPtr,
- PixelsPerLine, 0);
+ Error = dsp_static_sad8x8 (SrcPtr, PixelsPerLine, CandidateBlockPtr,
+ PixelsPerLine + STRIDE_EXTRA);
/* Was this the best so far */
if ( Error < MinError ) {
@@ -911,6 +727,8 @@
MOTION_VECTOR *MV ) {
ogg_uint32_t InterMVError;
+ dsp_static_save_fpu ();
+
/* For the moment the 4MV mode is only deemd to be valid if all four
Y blocks are to be updated */
/* This May be adapted later. */
@@ -941,6 +759,8 @@
InterMVError = HUGE_ERROR;
}
+ dsp_static_restore_fpu ();
+
/* Return score of best matching block. */
return InterMVError;
}
Index: lib/dct_decode.c
===================================================================
--- lib/dct_decode.c (revision 7621)
+++ lib/dct_decode.c (working copy)
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "encoder_internal.h"
+#include "dsp.h"
#define GOLDEN_FRAME_THRESH_Q 50
@@ -112,22 +113,6 @@
SetupBoundingValueArray_Generic(pbi, FLimit);
}
-void CopyBlock(unsigned char *src,
- unsigned char *dest,
- unsigned int srcstride){
- unsigned char *s = src;
- unsigned char *d = dest;
- unsigned int stride = srcstride;
-
- int j;
- for ( j = 0; j < 8; j++ ){
- ((ogg_uint32_t*)d)[0] = ((ogg_uint32_t*)s)[0];
- ((ogg_uint32_t*)d)[1] = ((ogg_uint32_t*)s)[1];
- s+=stride;
- d+=stride;
- }
-}
-
static void ExpandKFBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
ogg_uint32_t ReconPixelsPerLine;
ogg_int32_t ReconPixelIndex;
@@ -160,9 +145,8 @@
ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
/* Get the pixel index for the first pixel in the fragment. */
- ReconIntra( pbi, (unsigned char *)(&pbi->ThisFrameRecon[ReconPixelIndex]),
- (ogg_int16_t *)pbi->ReconDataBuffer, ReconPixelsPerLine );
-
+ dsp_static_recon_intra8x8 ((unsigned char *)(&pbi->ThisFrameRecon[ReconPixelIndex]),
+ (ogg_uint16_t *)pbi->ReconDataBuffer, ReconPixelsPerLine);
}
static void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
@@ -237,10 +221,9 @@
/* Reconstruct the pixel data using the last frame reconstruction
and change data when the motion vector is (0,0), the recon is
based on the lastframe without loop filtering---- for testing */
- ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex],
+ dsp_static_recon_inter8x8 (&pbi->ThisFrameRecon[ReconPixelIndex],
&pbi->LastFrameRecon[ReconPixelIndex],
- pbi->ReconDataBuffer, ReconPixelsPerLine );
-
+ pbi->ReconDataBuffer, ReconPixelsPerLine);
}else if ( ModeUsesMC[pbi->CodingMode] ) {
/* The mode uses a motion vector. */
/* Get vector from list */
@@ -287,29 +270,30 @@
if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 ) {
/* Reconstruct the pixel dats from the reference frame and change data
(no half pixel in this case as the two references were the same. */
- ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex],
+ dsp_static_recon_inter8x8 (
+ &pbi->ThisFrameRecon[ReconPixelIndex],
LastFrameRecPtr, pbi->ReconDataBuffer,
- ReconPixelsPerLine );
+ ReconPixelsPerLine);
}else{
/* Fractional pixel reconstruction. */
/* Note that we only use two pixels per reconstruction even for
the diagonal. */
- ReconInterHalfPixel2( pbi,&pbi->ThisFrameRecon[ReconPixelIndex],
+ dsp_static_recon_inter8x8_half(&pbi->ThisFrameRecon[ReconPixelIndex],
LastFrameRecPtr, LastFrameRecPtr2,
- pbi->ReconDataBuffer, ReconPixelsPerLine );
+ pbi->ReconDataBuffer, ReconPixelsPerLine);
}
} else if ( pbi->CodingMode == CODE_USING_GOLDEN ){
/* Golden frame with motion vector */
/* Reconstruct the pixel data using the golden frame
reconstruction and change data */
- ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex],
+ dsp_static_recon_inter8x8 (&pbi->ThisFrameRecon[ReconPixelIndex],
&pbi->GoldenFrame[ ReconPixelIndex ],
- pbi->ReconDataBuffer, ReconPixelsPerLine );
+ pbi->ReconDataBuffer, ReconPixelsPerLine);
} else {
/* Simple Intra coding */
/* Get the pixel index for the first pixel in the fragment. */
- ReconIntra( pbi, &pbi->ThisFrameRecon[ReconPixelIndex],
- pbi->ReconDataBuffer, ReconPixelsPerLine );
+ dsp_static_recon_intra8x8 (&pbi->ThisFrameRecon[ReconPixelIndex],
+ pbi->ReconDataBuffer, ReconPixelsPerLine);
}
}
@@ -464,7 +448,7 @@
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
- CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
+ dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
@@ -476,7 +460,7 @@
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
- CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
+ dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
@@ -501,7 +485,7 @@
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
- CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
+ dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
@@ -513,7 +497,7 @@
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
- CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
+ dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
Index: lib/pp.c
===================================================================
--- lib/pp.c (revision 7621)
+++ lib/pp.c (working copy)
@@ -19,6 +19,7 @@
#include <string.h>
#include "encoder_internal.h"
#include "pp.h"
+#include "dsp.h"
#define MAX(a, b) ((a>b)?a:b)
#define MIN(a, b) ((a<b)?a:b)
@@ -490,7 +491,7 @@
} else {
- CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+ dsp_static_copy8x8(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
}
@@ -529,7 +530,7 @@
DeringBlockWeak(SrcPtr + 8 * col, DestPtr + 8 * col,
LineLength,Quality,QuantScale);
}else{
- CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+ dsp_static_copy8x8(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
}
++Block;
@@ -565,7 +566,7 @@
DeringBlockWeak(SrcPtr + 8 * col, DestPtr + 8 * col,
LineLength,Quality,QuantScale);
}else{
- CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+ dsp_static_copy8x8(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
}
++Block;
Index: lib/encoder_internal.h
===================================================================
--- lib/encoder_internal.h (revision 7621)
+++ lib/encoder_internal.h (working copy)
@@ -24,6 +24,7 @@
#include <theora/theora.h>
#include "huffman.h"
+#include "dsp.h"
#ifndef LIBOGG2
#define theora_read(x,y,z) ( *z = oggpackB_read(x,y) )
@@ -689,23 +690,9 @@
ogg_int16_t *QuantMatrix,
ogg_int16_t * OutputData );
-extern void ReconIntra( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- ogg_int16_t * ChangePtr, ogg_uint32_t LineStep );
+extern void dsp_recon_init (DspFunctions *funcs);
-extern void ReconInter( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- unsigned char * RefPtr, ogg_int16_t * ChangePtr,
- ogg_uint32_t LineStep ) ;
-
-extern void ReconInterHalfPixel2( PB_INSTANCE *pbi, unsigned char * ReconPtr,
- unsigned char * RefPtr1,
- unsigned char * RefPtr2,
- ogg_int16_t * ChangePtr,
- ogg_uint32_t LineStep ) ;
-
extern void SetupLoopFilter(PB_INSTANCE *pbi);
-extern void CopyBlock(unsigned char *src,
- unsigned char *dest,
- unsigned int srcstride);
extern void LoopFilter(PB_INSTANCE *pbi);
extern void ReconRefFrames (PB_INSTANCE *pbi);
extern void ExpandToken( Q_LIST_ENTRY * ExpandedBlock,
Index: lib/scan.c
===================================================================
--- lib/scan.c (revision 7621)
+++ lib/scan.c (working copy)
@@ -19,9 +19,20 @@
#include <math.h>
#include <string.h>
#include "encoder_internal.h"
+#include "dsp.h"
#define MAX_SEARCH_LINE_LEN 7
+#define SET8_0(ptr) \
+ ((ogg_uint32_t *)ptr)[0] = 0x00000000; \
+ ((ogg_uint32_t *)ptr)[1] = 0x00000000;
+#define SET8_1(ptr) \
+ ((ogg_uint32_t *)ptr)[0] = 0x01010101; \
+ ((ogg_uint32_t *)ptr)[1] = 0x01010101;
+#define SET8_8(ptr) \
+ ((ogg_uint32_t *)ptr)[0] = 0x08080808; \
+ ((ogg_uint32_t *)ptr)[1] = 0x08080808;
+
static ogg_uint32_t LineLengthScores[ MAX_SEARCH_LINE_LEN + 1 ] = {
0, 0, 0, 0, 2, 4, 12, 24
};
@@ -384,69 +395,6 @@
ppi->KFIndicator = ((ppi->KFIndicator*100)/((ppi->ScanYPlaneFragments*3)/4));
}
-static ogg_uint32_t ScalarRowSAD( unsigned char * Src1,
- unsigned char * Src2 ){
- ogg_uint32_t SadValue;
- ogg_uint32_t SadValue1;
-
- SadValue = abs( Src1[0] - Src2[0] ) + abs( Src1[1] - Src2[1] ) +
- abs( Src1[2] - Src2[2] ) + abs( Src1[3] - Src2[3] );
-
- SadValue1 = abs( Src1[4] - Src2[4] ) + abs( Src1[5] - Src2[5] ) +
- abs( Src1[6] - Src2[6] ) + abs( Src1[7] - Src2[7] );
-
- SadValue = ( SadValue > SadValue1 ) ? SadValue : SadValue1;
-
- return SadValue;
-}
-
-static ogg_uint32_t ScalarColSAD( PP_INSTANCE *ppi,
- unsigned char * Src1,
- unsigned char * Src2 ){
- ogg_uint32_t SadValue[8] = {0,0,0,0,0,0,0,0};
- ogg_uint32_t SadValue2[8] = {0,0,0,0,0,0,0,0};
- ogg_uint32_t MaxSad = 0;
- ogg_uint32_t i;
-
- for ( i = 0; i < 4; i++ ){
- SadValue[0] += abs(Src1[0] - Src2[0]);
- SadValue[1] += abs(Src1[1] - Src2[1]);
- SadValue[2] += abs(Src1[2] - Src2[2]);
- SadValue[3] += abs(Src1[3] - Src2[3]);
- SadValue[4] += abs(Src1[4] - Src2[4]);
- SadValue[5] += abs(Src1[5] - Src2[5]);
- SadValue[6] += abs(Src1[6] - Src2[6]);
- SadValue[7] += abs(Src1[7] - Src2[7]);
-
- Src1 += ppi->PlaneStride;
- Src2 += ppi->PlaneStride;
- }
-
- for ( i = 0; i < 4; i++ ){
- SadValue2[0] += abs(Src1[0] - Src2[0]);
- SadValue2[1] += abs(Src1[1] - Src2[1]);
- SadValue2[2] += abs(Src1[2] - Src2[2]);
- SadValue2[3] += abs(Src1[3] - Src2[3]);
- SadValue2[4] += abs(Src1[4] - Src2[4]);
- SadValue2[5] += abs(Src1[5] - Src2[5]);
- SadValue2[6] += abs(Src1[6] - Src2[6]);
- SadValue2[7] += abs(Src1[7] - Src2[7]);
-
- Src1 += ppi->PlaneStride;
- Src2 += ppi->PlaneStride;
- }
-
- for ( i = 0; i < 8; i++ ){
- if ( SadValue[i] > MaxSad )
- MaxSad = SadValue[i];
- if ( SadValue2[i] > MaxSad )
- MaxSad = SadValue2[i];
- }
-
- return MaxSad;
-}
-
-
static int RowSadScan( PP_INSTANCE *ppi,
unsigned char * YuvPtr1,
unsigned char * YuvPtr2,
@@ -475,7 +423,7 @@
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
/* Calculate the SAD score for the block row */
- GrpSad = ScalarRowSAD(LocalYuvPtr1,LocalYuvPtr2);
+ GrpSad = dsp_static_row_sad8(LocalYuvPtr1,LocalYuvPtr2);
/* Now test the group SAD score */
if ( GrpSad > LocalGrpLowSadThresh ){
@@ -532,7 +480,7 @@
/* Skip if block already marked to be coded. */
if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
/* Calculate the SAD score for the block column */
- MaxSad = ScalarColSAD( ppi, LocalYuvPtr1, LocalYuvPtr2 );
+ MaxSad = dsp_static_col_sad8x8(LocalYuvPtr1, LocalYuvPtr2, ppi->PlaneStride );
/* Now test the group SAD score */
if ( MaxSad > LocalGrpLowSadThresh ){
@@ -758,7 +706,7 @@
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
@@ -777,10 +725,10 @@
}else{
/* If we are breaking out here mark all pixels as changed. */
if ( *DispFragPtr > BLOCK_NOT_CODED ){
- memset(bits_map_ptr,1,8);
- memset(ChLocalsPtr,8,8);
+ SET8_1(bits_map_ptr);
+ SET8_8(ChLocalsPtr);
}else{
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
}
}
@@ -816,7 +764,7 @@
/* Test for break out conditions to save time. */
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
@@ -839,10 +787,10 @@
}else{
/* If we are breaking out here mark all pixels as changed. */
if ( *DispFragPtr > BLOCK_NOT_CODED ){
- memset(bits_map_ptr,1,8);
- memset(ChLocalsPtr,8,8);
+ SET8_1(bits_map_ptr);
+ SET8_8(ChLocalsPtr);
}else{
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
}
}
@@ -876,7 +824,7 @@
/* Test for break out conditions to save time. */
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
@@ -899,10 +847,10 @@
}else{
/* If we are breaking out here mark all pixels as changed. */
if ( *DispFragPtr > BLOCK_NOT_CODED ){
- memset(bits_map_ptr,1,8);
- memset(ChLocalsPtr,8,8);
+ SET8_1(bits_map_ptr);
+ SET8_8(ChLocalsPtr);
}else{
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
}
}
@@ -935,7 +883,7 @@
/* Test for break out conditions to save time. */
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
@@ -959,10 +907,10 @@
}else{
/* If we are breaking out here mark all pixels as changed.*/
if ( *DispFragPtr > BLOCK_NOT_CODED ) {
- memset(bits_map_ptr,1,8);
- memset(ChLocalsPtr,8,8);
+ SET8_1(bits_map_ptr);
+ SET8_8(ChLocalsPtr);
}else{
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
}
}
/* If we have a lot of changed pixels for this fragment on this
@@ -1071,7 +1019,7 @@
}
}else{
if ( *DispFragPtr > BLOCK_NOT_CODED )
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
/* Step pointers */
ChLocalsPtr += HFRAGPIXELS;
@@ -1133,7 +1081,7 @@
}
}else{
if ( *DispFragPtr > BLOCK_NOT_CODED )
- memset(ChLocalsPtr,0,8);
+ SET8_0(ChLocalsPtr);
/* Step pointers */
ChLocalsPtr += HFRAGPIXELS;
@@ -2126,10 +2074,12 @@
/* Fast break out test for obvious yes and no cases in this row of
blocks */
if ( i < ppi->PlaneVFragments ){
+ dsp_static_save_fpu ();
UpdatedOrCandidateBlocks =
RowSadScan( ppi, RawPlanePtr0, RawPlanePtr1, DispFragPtr0 );
- if( ColSadScan( ppi, RawPlanePtr0, RawPlanePtr1, DispFragPtr0 ) )
- UpdatedOrCandidateBlocks = 1;
+ UpdatedOrCandidateBlocks |=
+ ColSadScan( ppi, RawPlanePtr0, RawPlanePtr1, DispFragPtr0 );
+ dsp_static_restore_fpu ();
}else{
/* Make sure we still call other functions if RowSadScan() disabled */
UpdatedOrCandidateBlocks = 1;
Index: lib/dsp.c
===================================================================
--- lib/dsp.c (revision 0)
+++ lib/dsp.c (revision 0)
@@ -0,0 +1,416 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include "cpu.h"
+#include "encoder_internal.h"
+
+#define DSP_OP_AVG(a,b) ((((int)(a)) + ((int)(b)))/2)
+#define DSP_OP_DIFF(a,b) (((int)(a)) - ((int)(b)))
+#define DSP_OP_ABS_DIFF(a,b) abs((((int)(a)) - ((int)(b))))
+
+DspFunctions dsp_funcs;
+
+static void sub8x8__c (unsigned char *FiltPtr, unsigned char *ReconPtr,
+ ogg_int16_t *DctInputPtr, ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine) {
+ int i;
+
+ /* For each block row */
+ for (i=8; i; i--) {
+ DctInputPtr[0] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[0], ReconPtr[0]);
+ DctInputPtr[1] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[1], ReconPtr[1]);
+ DctInputPtr[2] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[2], ReconPtr[2]);
+ DctInputPtr[3] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[3], ReconPtr[3]);
+ DctInputPtr[4] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[4], ReconPtr[4]);
+ DctInputPtr[5] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[5], ReconPtr[5]);
+ DctInputPtr[6] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[6], ReconPtr[6]);
+ DctInputPtr[7] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[7], ReconPtr[7]);
+
+ /* Start next row */
+ FiltPtr += PixelsPerLine;
+ ReconPtr += ReconPixelsPerLine;
+ DctInputPtr += 8;
+ }
+}
+
+static void sub8x8_128__c (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine) {
+ int i;
+ /* For each block row */
+ for (i=8; i; i--) {
+ /* INTRA mode so code raw image data */
+ /* We convert the data to 8 bit signed (by subtracting 128) as
+ this reduces the internal precision requirments in the DCT
+ transform. */
+ DctInputPtr[0] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[0], 128);
+ DctInputPtr[1] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[1], 128);
+ DctInputPtr[2] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[2], 128);
+ DctInputPtr[3] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[3], 128);
+ DctInputPtr[4] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[4], 128);
+ DctInputPtr[5] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[5], 128);
+ DctInputPtr[6] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[6], 128);
+ DctInputPtr[7] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[7], 128);
+
+ /* Start next row */
+ FiltPtr += PixelsPerLine;
+ DctInputPtr += 8;
+ }
+}
+
+static void sub8x8avg2__c (unsigned char *FiltPtr, unsigned char *ReconPtr1,
+ unsigned char *ReconPtr2, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine)
+{
+ int i;
+
+ /* For each block row */
+ for (i=8; i; i--) {
+ DctInputPtr[0] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[0], DSP_OP_AVG (ReconPtr1[0], ReconPtr2[0]));
+ DctInputPtr[1] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[1], DSP_OP_AVG (ReconPtr1[1], ReconPtr2[1]));
+ DctInputPtr[2] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[2], DSP_OP_AVG (ReconPtr1[2], ReconPtr2[2]));
+ DctInputPtr[3] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[3], DSP_OP_AVG (ReconPtr1[3], ReconPtr2[3]));
+ DctInputPtr[4] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[4], DSP_OP_AVG (ReconPtr1[4], ReconPtr2[4]));
+ DctInputPtr[5] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[5], DSP_OP_AVG (ReconPtr1[5], ReconPtr2[5]));
+ DctInputPtr[6] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[6], DSP_OP_AVG (ReconPtr1[6], ReconPtr2[6]));
+ DctInputPtr[7] = (ogg_int16_t) DSP_OP_DIFF (FiltPtr[7], DSP_OP_AVG (ReconPtr1[7], ReconPtr2[7]));
+
+ /* Start next row */
+ FiltPtr += PixelsPerLine;
+ ReconPtr1 += ReconPixelsPerLine;
+ ReconPtr2 += ReconPixelsPerLine;
+ DctInputPtr += 8;
+ }
+}
+
+static ogg_uint32_t row_sad8__c (unsigned char *Src1, unsigned char *Src2)
+{
+ ogg_uint32_t SadValue;
+ ogg_uint32_t SadValue1;
+
+ SadValue = DSP_OP_ABS_DIFF (Src1[0], Src2[0]) +
+ DSP_OP_ABS_DIFF (Src1[1], Src2[1]) +
+ DSP_OP_ABS_DIFF (Src1[2], Src2[2]) +
+ DSP_OP_ABS_DIFF (Src1[3], Src2[3]);
+
+ SadValue1 = DSP_OP_ABS_DIFF (Src1[4], Src2[4]) +
+ DSP_OP_ABS_DIFF (Src1[5], Src2[5]) +
+ DSP_OP_ABS_DIFF (Src1[6], Src2[6]) +
+ DSP_OP_ABS_DIFF (Src1[7], Src2[7]);
+
+ SadValue = ( SadValue > SadValue1 ) ? SadValue : SadValue1;
+
+ return SadValue;
+}
+
+static ogg_uint32_t col_sad8x8__c (unsigned char *Src1, unsigned char *Src2,
+ ogg_uint32_t stride)
+{
+ ogg_uint32_t SadValue[8] = {0,0,0,0,0,0,0,0};
+ ogg_uint32_t SadValue2[8] = {0,0,0,0,0,0,0,0};
+ ogg_uint32_t MaxSad = 0;
+ ogg_uint32_t i;
+
+ for ( i = 0; i < 4; i++ ){
+ SadValue[0] += abs(Src1[0] - Src2[0]);
+ SadValue[1] += abs(Src1[1] - Src2[1]);
+ SadValue[2] += abs(Src1[2] - Src2[2]);
+ SadValue[3] += abs(Src1[3] - Src2[3]);
+ SadValue[4] += abs(Src1[4] - Src2[4]);
+ SadValue[5] += abs(Src1[5] - Src2[5]);
+ SadValue[6] += abs(Src1[6] - Src2[6]);
+ SadValue[7] += abs(Src1[7] - Src2[7]);
+
+ Src1 += stride;
+ Src2 += stride;
+ }
+
+ for ( i = 0; i < 4; i++ ){
+ SadValue2[0] += abs(Src1[0] - Src2[0]);
+ SadValue2[1] += abs(Src1[1] - Src2[1]);
+ SadValue2[2] += abs(Src1[2] - Src2[2]);
+ SadValue2[3] += abs(Src1[3] - Src2[3]);
+ SadValue2[4] += abs(Src1[4] - Src2[4]);
+ SadValue2[5] += abs(Src1[5] - Src2[5]);
+ SadValue2[6] += abs(Src1[6] - Src2[6]);
+ SadValue2[7] += abs(Src1[7] - Src2[7]);
+
+ Src1 += stride;
+ Src2 += stride;
+ }
+
+ for ( i = 0; i < 8; i++ ){
+ if ( SadValue[i] > MaxSad )
+ MaxSad = SadValue[i];
+ if ( SadValue2[i] > MaxSad )
+ MaxSad = SadValue2[i];
+ }
+
+ return MaxSad;
+}
+
+static ogg_uint32_t sad8x8__c (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t sad = 0;
+
+ for (i=8; i; i--) {
+ sad += DSP_OP_ABS_DIFF(ptr1[0], ptr2[0]);
+ sad += DSP_OP_ABS_DIFF(ptr1[1], ptr2[1]);
+ sad += DSP_OP_ABS_DIFF(ptr1[2], ptr2[2]);
+ sad += DSP_OP_ABS_DIFF(ptr1[3], ptr2[3]);
+ sad += DSP_OP_ABS_DIFF(ptr1[4], ptr2[4]);
+ sad += DSP_OP_ABS_DIFF(ptr1[5], ptr2[5]);
+ sad += DSP_OP_ABS_DIFF(ptr1[6], ptr2[6]);
+ sad += DSP_OP_ABS_DIFF(ptr1[7], ptr2[7]);
+
+ /* Step to next row of block. */
+ ptr1 += stride1;
+ ptr2 += stride2;
+ }
+
+ return sad;
+}
+
+static ogg_uint32_t sad8x8_thres__c (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2,
+ ogg_uint32_t thres)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t sad = 0;
+
+ for (i=8; i; i--) {
+ sad += DSP_OP_ABS_DIFF(ptr1[0], ptr2[0]);
+ sad += DSP_OP_ABS_DIFF(ptr1[1], ptr2[1]);
+ sad += DSP_OP_ABS_DIFF(ptr1[2], ptr2[2]);
+ sad += DSP_OP_ABS_DIFF(ptr1[3], ptr2[3]);
+ sad += DSP_OP_ABS_DIFF(ptr1[4], ptr2[4]);
+ sad += DSP_OP_ABS_DIFF(ptr1[5], ptr2[5]);
+ sad += DSP_OP_ABS_DIFF(ptr1[6], ptr2[6]);
+ sad += DSP_OP_ABS_DIFF(ptr1[7], ptr2[7]);
+
+ if (sad > thres )
+ break;
+
+ /* Step to next row of block. */
+ ptr1 += stride1;
+ ptr2 += stride2;
+ }
+
+ return sad;
+}
+
+static ogg_uint32_t sad8x8_xy2_thres__c (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride,
+ ogg_uint32_t thres)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t sad = 0;
+
+ for (i=8; i; i--) {
+ sad += DSP_OP_ABS_DIFF(SrcData[0], DSP_OP_AVG (RefDataPtr1[0], RefDataPtr2[0]));
+ sad += DSP_OP_ABS_DIFF(SrcData[1], DSP_OP_AVG (RefDataPtr1[1], RefDataPtr2[1]));
+ sad += DSP_OP_ABS_DIFF(SrcData[2], DSP_OP_AVG (RefDataPtr1[2], RefDataPtr2[2]));
+ sad += DSP_OP_ABS_DIFF(SrcData[3], DSP_OP_AVG (RefDataPtr1[3], RefDataPtr2[3]));
+ sad += DSP_OP_ABS_DIFF(SrcData[4], DSP_OP_AVG (RefDataPtr1[4], RefDataPtr2[4]));
+ sad += DSP_OP_ABS_DIFF(SrcData[5], DSP_OP_AVG (RefDataPtr1[5], RefDataPtr2[5]));
+ sad += DSP_OP_ABS_DIFF(SrcData[6], DSP_OP_AVG (RefDataPtr1[6], RefDataPtr2[6]));
+ sad += DSP_OP_ABS_DIFF(SrcData[7], DSP_OP_AVG (RefDataPtr1[7], RefDataPtr2[7]));
+
+ if ( sad > thres )
+ break;
+
+ /* Step to next row of block. */
+ SrcData += SrcStride;
+ RefDataPtr1 += RefStride;
+ RefDataPtr2 += RefStride;
+ }
+
+ return sad;
+}
+
+static ogg_uint32_t intra8x8_err__c (unsigned char *DataPtr, ogg_uint32_t Stride)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t XSum=0;
+ ogg_uint32_t XXSum=0;
+
+ for (i=8; i; i--) {
+ /* Examine alternate pixel locations. */
+ XSum += DataPtr[0];
+ XXSum += DataPtr[0]*DataPtr[0];
+ XSum += DataPtr[1];
+ XXSum += DataPtr[1]*DataPtr[1];
+ XSum += DataPtr[2];
+ XXSum += DataPtr[2]*DataPtr[2];
+ XSum += DataPtr[3];
+ XXSum += DataPtr[3]*DataPtr[3];
+ XSum += DataPtr[4];
+ XXSum += DataPtr[4]*DataPtr[4];
+ XSum += DataPtr[5];
+ XXSum += DataPtr[5]*DataPtr[5];
+ XSum += DataPtr[6];
+ XXSum += DataPtr[6]*DataPtr[6];
+ XSum += DataPtr[7];
+ XXSum += DataPtr[7]*DataPtr[7];
+
+ /* Step to next row of block. */
+ DataPtr += Stride;
+ }
+
+ /* Compute population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ) );
+}
+
+static ogg_uint32_t inter8x8_err__c (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr, ogg_uint32_t RefStride)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t XSum=0;
+ ogg_uint32_t XXSum=0;
+ ogg_int32_t DiffVal;
+
+ for (i=8; i; i--) {
+ DiffVal = DSP_OP_DIFF (SrcData[0], RefDataPtr[0]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[1], RefDataPtr[1]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[2], RefDataPtr[2]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[3], RefDataPtr[3]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[4], RefDataPtr[4]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[5], RefDataPtr[5]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[6], RefDataPtr[6]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF (SrcData[7], RefDataPtr[7]);
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ /* Step to next row of block. */
+ SrcData += SrcStride;
+ RefDataPtr += RefStride;
+ }
+
+ /* Compute and return population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ));
+}
+
+static ogg_uint32_t inter8x8_err_xy2__c (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride)
+{
+ ogg_uint32_t i;
+ ogg_uint32_t XSum=0;
+ ogg_uint32_t XXSum=0;
+ ogg_int32_t DiffVal;
+
+ for (i=8; i; i--) {
+ DiffVal = DSP_OP_DIFF(SrcData[0], DSP_OP_AVG (RefDataPtr1[0], RefDataPtr2[0]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[1], DSP_OP_AVG (RefDataPtr1[1], RefDataPtr2[1]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[2], DSP_OP_AVG (RefDataPtr1[2], RefDataPtr2[2]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[3], DSP_OP_AVG (RefDataPtr1[3], RefDataPtr2[3]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[4], DSP_OP_AVG (RefDataPtr1[4], RefDataPtr2[4]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[5], DSP_OP_AVG (RefDataPtr1[5], RefDataPtr2[5]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[6], DSP_OP_AVG (RefDataPtr1[6], RefDataPtr2[6]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ DiffVal = DSP_OP_DIFF(SrcData[7], DSP_OP_AVG (RefDataPtr1[7], RefDataPtr2[7]));
+ XSum += DiffVal;
+ XXSum += DiffVal*DiffVal;
+
+ /* Step to next row of block. */
+ SrcData += SrcStride;
+ RefDataPtr1 += RefStride;
+ RefDataPtr2 += RefStride;
+ }
+
+ /* Compute and return population variance as mis-match metric. */
+ return (( (XXSum<<6) - XSum*XSum ));
+}
+
+static void nop (void) { /* NOP */ }
+
+void dsp_init(DspFunctions *funcs)
+{
+ funcs->save_fpu = nop;
+ funcs->restore_fpu = nop;
+ funcs->sub8x8 = sub8x8__c;
+ funcs->sub8x8_128 = sub8x8_128__c;
+ funcs->sub8x8avg2 = sub8x8avg2__c;
+ funcs->row_sad8 = row_sad8__c;
+ funcs->col_sad8x8 = col_sad8x8__c;
+ funcs->sad8x8 = sad8x8__c;
+ funcs->sad8x8_thres = sad8x8_thres__c;
+ funcs->sad8x8_xy2_thres = sad8x8_xy2_thres__c;
+ funcs->intra8x8_err = intra8x8_err__c;
+ funcs->inter8x8_err = inter8x8_err__c;
+ funcs->inter8x8_err_xy2 = inter8x8_err_xy2__c;
+}
+
+void dsp_static_init(void)
+{
+ cpu_init ();
+ dsp_init (&dsp_funcs);
+ dsp_recon_init (&dsp_funcs);
+ dsp_dct_init (&dsp_funcs);
+ if (cpu_flags & CPU_X86_MMX) {
+ dsp_i386_mmx_init(&dsp_funcs);
+ }
+ if (cpu_flags & CPU_X86_MMXEXT) {
+ dsp_i386_mmxext_init(&dsp_funcs);
+ }
+}
+
Index: lib/Makefile.am
===================================================================
--- lib/Makefile.am (revision 7621)
+++ lib/Makefile.am (working copy)
@@ -3,12 +3,13 @@
lib_LTLIBRARIES = libtheora.la
if THEORA_SUPPORT_ENCODE
-encoder_sources = dct_encode.c encode.c encoder_toplevel.c
+encoder_sources = dct_encode.c encode.c encoder_toplevel.c
else
encoder_sources = encoder_disabled.c
endif
libtheora_la_SOURCES = \
+ cpu.c dsp.h dsp.c i386/dsp_mmx.c i386/dsp_mmxext.c i386/recon_mmx.c i386/fdct_mmx.c \
blockmap.c \
comment.c \
dct.c \
Index: lib/blockmap.c
===================================================================
--- lib/blockmap.c (revision 7621)
+++ lib/blockmap.c (working copy)
@@ -21,7 +21,7 @@
ogg_uint32_t FirstSB,
ogg_uint32_t FirstFrag, ogg_uint32_t HFrags,
ogg_uint32_t VFrags ){
- ogg_uint32_t i, j;
+ ogg_uint32_t i, j = 0;
ogg_uint32_t xpos;
ogg_uint32_t ypos;
ogg_uint32_t SBrow, SBcol;
Index: lib/encoder_toplevel.c
===================================================================
--- lib/encoder_toplevel.c (revision 7621)
+++ lib/encoder_toplevel.c (working copy)
@@ -777,6 +777,8 @@
CP_INSTANCE *cpi;
+ dsp_static_init ();
+
memset(th, 0, sizeof(*th));
th->internal_encode=cpi=_ogg_calloc(1,sizeof(*cpi));
Index: lib/toplevel.c
===================================================================
--- lib/toplevel.c (revision 7621)
+++ lib/toplevel.c (working copy)
@@ -290,6 +290,8 @@
PB_INSTANCE *pbi;
codec_setup_info *ci;
+ dsp_static_init ();
+
ci=(codec_setup_info *)c->codec_setup;
th->internal_decode=pbi=_ogg_calloc(1,sizeof(*pbi));
Index: lib/dsp.h
===================================================================
--- lib/dsp.h (revision 0)
+++ lib/dsp.h (revision 0)
@@ -0,0 +1,154 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function:
+ last mod: $Id: mcomp.c,v 1.8 2003/12/03 08:59:41 arc Exp $
+
+ ********************************************************************/
+
+#ifndef DSP_H
+#define DSP_H
+
+#include <theora/theora.h>
+
+typedef struct
+{
+ void (*save_fpu) (void);
+ void (*restore_fpu) (void);
+
+ void (*sub8x8) (unsigned char *FiltPtr, unsigned char *ReconPtr,
+ ogg_int16_t *DctInputPtr, ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine);
+
+ void (*sub8x8_128) (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine);
+
+ void (*sub8x8avg2) (unsigned char *FiltPtr, unsigned char *ReconPtr1,
+ unsigned char *ReconPtr2, ogg_int16_t *DctInputPtr,
+ ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t ReconPixelsPerLine);
+
+ void (*copy8x8) (unsigned char *src, unsigned char *dest,
+ ogg_uint32_t stride);
+
+ void (*recon_intra8x8) (unsigned char *ReconPtr, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep);
+
+ void (*recon_inter8x8) (unsigned char *ReconPtr, unsigned char *RefPtr,
+ ogg_int16_t *ChangePtr, ogg_uint32_t LineStep);
+
+ void (*recon_inter8x8_half) (unsigned char *ReconPtr, unsigned char *RefPtr1,
+ unsigned char *RefPtr2, ogg_int16_t *ChangePtr,
+ ogg_uint32_t LineStep);
+
+ void (*fdct_short) (ogg_int16_t *InputData, ogg_int16_t *OutputData);
+
+ ogg_uint32_t (*row_sad8) (unsigned char *Src1, unsigned char *Src2);
+
+ ogg_uint32_t (*col_sad8x8) (unsigned char *Src1, unsigned char *Src2,
+ ogg_uint32_t stride);
+
+ ogg_uint32_t (*sad8x8) (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2);
+
+ ogg_uint32_t (*sad8x8_thres) (unsigned char *ptr1, ogg_uint32_t stride1,
+ unsigned char *ptr2, ogg_uint32_t stride2,
+ ogg_uint32_t thres);
+
+ ogg_uint32_t (*sad8x8_xy2_thres)(unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride,
+ ogg_uint32_t thres);
+
+ ogg_uint32_t (*intra8x8_err) (unsigned char *DataPtr, ogg_uint32_t Stride);
+
+ ogg_uint32_t (*inter8x8_err) (unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr, ogg_uint32_t RefStride);
+
+ ogg_uint32_t (*inter8x8_err_xy2)(unsigned char *SrcData, ogg_uint32_t SrcStride,
+ unsigned char *RefDataPtr1,
+ unsigned char *RefDataPtr2, ogg_uint32_t RefStride);
+} DspFunctions;
+
+extern DspFunctions dsp_funcs;
+
+extern void dsp_recon_init (DspFunctions *funcs);
+
+void dsp_init(DspFunctions *funcs);
+void dsp_static_init(void);
+
+#define dsp_save_fpu(funcs) (funcs.save_fpu ())
+#define dsp_static_save_fpu() dsp_save_fpu(dsp_funcs)
+
+#define dsp_restore_fpu(funcs) (funcs.restore_fpu ())
+#define dsp_static_restore_fpu() dsp_restore_fpu(dsp_funcs)
+
+#define dsp_sub8x8(funcs,a1,a2,a3,a4,a5) (funcs.sub8x8 (a1,a2,a3,a4,a5))
+#define dsp_static_sub8x8(a1,a2,a3,a4,a5) dsp_sub8x8(dsp_funcs,a1,a2,a3,a4,a5)
+
+#define dsp_sub8x8_128(funcs,a1,a2,a3) (funcs.sub8x8_128 (a1,a2,a3))
+#define dsp_static_sub8x8_128(a1,a2,a3) dsp_sub8x8_128(dsp_funcs,a1,a2,a3)
+
+#define dsp_sub8x8avg2(funcs,a1,a2,a3,a4,a5,a6) (funcs.sub8x8avg2 (a1,a2,a3,a4,a5,a6))
+#define dsp_static_sub8x8avg2(a1,a2,a3,a4,a5,a6) dsp_sub8x8avg2(dsp_funcs,a1,a2,a3,a4,a5,a6)
+
+#define dsp_copy8x8(funcs,ptr1,ptr2,str1) (funcs.copy8x8 (ptr1,ptr2,str1))
+#define dsp_static_copy8x8(ptr1,ptr2,str1) dsp_copy8x8(dsp_funcs,ptr1,ptr2,str1)
+
+#define dsp_recon_intra8x8(funcs,ptr1,ptr2,str1) (funcs.recon_intra8x8 (ptr1,ptr2,str1))
+#define dsp_static_recon_intra8x8(ptr1,ptr2,str1) dsp_recon_intra8x8(dsp_funcs,ptr1,ptr2,str1)
+
+#define dsp_recon_inter8x8(funcs,ptr1,ptr2,ptr3,str1) \
+ (funcs.recon_inter8x8 (ptr1,ptr2,ptr3,str1))
+#define dsp_static_recon_inter8x8(ptr1,ptr2,ptr3,str1) \
+ dsp_recon_inter8x8(dsp_funcs,ptr1,ptr2,ptr3,str1)
+
+#define dsp_recon_inter8x8_half(funcs,ptr1,ptr2,ptr3,ptr4,str1) \
+ (funcs.recon_inter8x8_half (ptr1,ptr2,ptr3,ptr4,str1))
+#define dsp_static_recon_inter8x8_half(ptr1,ptr2,ptr3,ptr4,str1) \
+ dsp_recon_inter8x8_half(dsp_funcs,ptr1,ptr2,ptr3,ptr4,str1)
+
+#define dsp_fdct_short(funcs,in,out) (funcs.fdct_short (in,out))
+#define dsp_static_fdct_short(in,out) dsp_fdct_short(dsp_funcs,in,out)
+
+#define dsp_row_sad8(funcs,ptr1,ptr2) (funcs.row_sad8 (ptr1,ptr2))
+#define dsp_static_row_sad8(ptr1,ptr2) dsp_row_sad8(dsp_funcs,ptr1,ptr2)
+
+#define dsp_col_sad8x8(funcs,ptr1,ptr2,str1) (funcs.col_sad8x8 (ptr1,ptr2,str1))
+#define dsp_static_col_sad8x8(ptr1,ptr2,str1) dsp_col_sad8x8(dsp_funcs,ptr1,ptr2,str1)
+
+#define dsp_sad8x8(funcs,ptr1,str1,ptr2,str2) (funcs.sad8x8 (ptr1,str1,ptr2,str2))
+#define dsp_static_sad8x8(ptr1,str1,ptr2,str2) dsp_sad8x8(dsp_funcs,ptr1,str1,ptr2,str2)
+
+#define dsp_sad8x8_thres(funcs,ptr1,str1,ptr2,str2,t) (funcs.sad8x8_thres (ptr1,str1,ptr2,str2,t))
+#define dsp_static_sad8x8_thres(ptr1,str1,ptr2,str2,t) dsp_sad8x8_thres(dsp_funcs,ptr1,str1,ptr2,str2,t)
+
+#define dsp_sad8x8_xy2_thres(funcs,ptr1,str1,ptr2,ptr3,str2,t) \
+ (funcs.sad8x8_xy2_thres (ptr1,str1,ptr2,ptr3,str2,t))
+#define dsp_static_sad8x8_xy2_thres(ptr1,str1,ptr2,ptr3,str2,t) \
+ dsp_sad8x8_xy2_thres(dsp_funcs,ptr1,str1,ptr2,ptr3,str2,t)
+
+#define dsp_intra8x8_err(funcs,ptr1,str1) (funcs.intra8x8_err (ptr1,str1))
+#define dsp_static_intra8x8_err(ptr1,str1) dsp_intra8x8_err(dsp_funcs,ptr1,str1)
+
+#define dsp_inter8x8_err(funcs,ptr1,str1,ptr2,str2) \
+ (funcs.inter8x8_err (ptr1,str1,ptr2,str2))
+#define dsp_static_inter8x8_err(ptr1,str1,ptr2,str2) \
+ dsp_inter8x8_err(dsp_funcs,ptr1,str1,ptr2,str2)
+
+#define dsp_inter8x8_err_xy2(funcs,ptr1,str1,ptr2,ptr3,str2) \
+ (funcs.inter8x8_err_xy2 (ptr1,str1,ptr2,ptr3,str2))
+#define dsp_static_inter8x8_err_xy2(ptr1,str1,ptr2,ptr3,str2) \
+ dsp_inter8x8_err_xy2(dsp_funcs,ptr1,str1,ptr2,ptr3,str2)
+
+
+#endif /* DSP_H */
Index: lib/encode.c
===================================================================
--- lib/encode.c (revision 7621)
+++ lib/encode.c (working copy)
@@ -531,8 +531,7 @@
static ogg_uint32_t GetBlockReconErrorSlow( CP_INSTANCE *cpi,
ogg_int32_t BlockIndex ) {
- ogg_uint32_t i;
- ogg_uint32_t ErrorVal = 0;
+ ogg_uint32_t ErrorVal;
unsigned char * SrcDataPtr =
&cpi->ConvDestBuffer[cpi->pb.pixel_index_table[BlockIndex]];
@@ -550,21 +549,8 @@
RecStride = cpi->pb.UVStride;
}
+ ErrorVal = dsp_static_sad8x8 (SrcDataPtr, SrcStride, RecDataPtr, RecStride);
- /* Decide on standard or MMX implementation */
- for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
- ErrorVal += abs( ((int)SrcDataPtr[0]) - ((int)RecDataPtr[0]) );
- ErrorVal += abs( ((int)SrcDataPtr[1]) - ((int)RecDataPtr[1]) );
- ErrorVal += abs( ((int)SrcDataPtr[2]) - ((int)RecDataPtr[2]) );
- ErrorVal += abs( ((int)SrcDataPtr[3]) - ((int)RecDataPtr[3]) );
- ErrorVal += abs( ((int)SrcDataPtr[4]) - ((int)RecDataPtr[4]) );
- ErrorVal += abs( ((int)SrcDataPtr[5]) - ((int)RecDataPtr[5]) );
- ErrorVal += abs( ((int)SrcDataPtr[6]) - ((int)RecDataPtr[6]) );
- ErrorVal += abs( ((int)SrcDataPtr[7]) - ((int)RecDataPtr[7]) );
- /* Step to next row of block. */
- SrcDataPtr += SrcStride;
- RecDataPtr += RecStride;
- }
return ErrorVal;
}
@@ -933,9 +919,13 @@
/* Zero Decoder EOB run count */
cpi->pb.EOB_Run = 0;
+ dsp_static_save_fpu ();
+
/* Encode any fragments coded using DCT. */
coded_pixels += QuadCodeDisplayFragments (cpi);
+ dsp_static_restore_fpu ();
+
return coded_pixels;
}
More information about the Theora-dev
mailing list