view motion_test.c @ 1352:e8ff4783f188 libavcodec

1) remove TBL support in PPC performance. It's much more useful to use the PMCs, and with Apple's CHUD it's fairly easy too. No reason to keep useless code around 2) make the PPC perf stuff a configure option 3) make put_pixels16_altivec a bit faster by unrolling the loop by 4 patch by (Romain Dolbeau <dolbeau at irisa dot fr>)
author michaelni
date Wed, 09 Jul 2003 20:18:13 +0000
parents 1e39f273ecd6
children ef2149182f1c
line wrap: on
line source

/* motion test. (c) 2001 Fabrice Bellard. */

/**
 * @file motion_test.c
 * motion test.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#include "dsputil.h"

#include "i386/mmx.h"

int pix_abs16x16_mmx(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_mmx1(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_x2_mmx(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_x2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_x2_c(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_y2_mmx(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_y2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_y2_c(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_xy2_mmx(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_xy2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx);
int pix_abs16x16_xy2_c(uint8_t *blk1, uint8_t *blk2, int lx);

typedef int motion_func(uint8_t *blk1, uint8_t *blk2, int lx);

#define WIDTH 64
#define HEIGHT 64

uint8_t img1[WIDTH * HEIGHT];
uint8_t img2[WIDTH * HEIGHT];

void fill_random(uint8_t *tab, int size)
{
    int i;
    for(i=0;i<size;i++) {
#if 1
        tab[i] = random() % 256;
#else
        tab[i] = i;
#endif
    }
}

void help(void)
{
    printf("motion-test [-h]\n"
           "test motion implementations\n");
    exit(1);
}

int64_t gettime(void)
{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}

#define NB_ITS 500

int dummy;

void test_motion(const char *name,
                 motion_func *test_func, motion_func *ref_func)
{
    int x, y, d1, d2, it;
    uint8_t *ptr;
    int64_t ti;
    printf("testing '%s'\n", name);

    /* test correctness */
    for(it=0;it<20;it++) {

        fill_random(img1, WIDTH * HEIGHT);
        fill_random(img2, WIDTH * HEIGHT);
        
        for(y=0;y<HEIGHT-17;y++) {
            for(x=0;x<WIDTH-17;x++) {
                ptr = img2 + y * WIDTH + x; 
                d1 = test_func(img1, ptr, WIDTH);
                d2 = ref_func(img1, ptr, WIDTH);
                if (d1 != d2) {
                    printf("error: mmx=%d c=%d\n", d1, d2);
                }
            }
        }
    }
    emms();
    
    /* speed test */
    ti = gettime();
    d1 = 0;
    for(it=0;it<NB_ITS;it++) {
        for(y=0;y<HEIGHT-17;y++) {
            for(x=0;x<WIDTH-17;x++) {
                ptr = img2 + y * WIDTH + x; 
                d1 += test_func(img1, ptr, WIDTH);
            }
        }
    }
    emms();
    dummy = d1; /* avoid optimisation */
    ti = gettime() - ti;
    
    printf("  %0.0f kop/s\n", 
           (double)NB_ITS * (WIDTH - 16) * (HEIGHT - 16) / 
           (double)(ti / 1000.0));
}


int main(int argc, char **argv)
{
    int c;
    
    for(;;) {
        c = getopt(argc, argv, "h");
        if (c == -1)
            break;
        switch(c) {
        case 'h':
            help();
            break;
        }
    }
               
    printf("ffmpeg motion test\n");

    test_motion("mmx", pix_abs16x16_mmx, pix_abs16x16_c);
    test_motion("mmx_x2", pix_abs16x16_x2_mmx, pix_abs16x16_x2_c);
    test_motion("mmx_y2", pix_abs16x16_y2_mmx, pix_abs16x16_y2_c);
    test_motion("mmx_xy2", pix_abs16x16_xy2_mmx, pix_abs16x16_xy2_c);
    return 0;
}