Skip to content
Snippets Groups Projects
dsputil.c 53.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •     qpel_v_lowpass(halfHV, halfH, 8, 8, 8, 16-r);\
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        avg2_block(dst, halfV, halfHV, dstStride, 8, 1-r);\
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    }\
    static void qpel_mc22_c ## name (UINT8 *dst, UINT8 *src, int dstStride, int srcStride, int mx, int my)\
    {\
        UINT8 halfH[72];\
    
        qpel_h_lowpass(halfH, src, 8, srcStride, 9, 16-r);\
        qpel_v_lowpass(dst, halfH, dstStride, 8, 8, 16-r);\
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    }\
    qpel_mc_func qpel_mc ## name ## _tab[16]={ \
        qpel_mc00_c ## name,                                                                   \
        qpel_mc10_c ## name,                                                                   \
        qpel_mc20_c ## name,                                                                   \
        qpel_mc30_c ## name,                                                                   \
        qpel_mc01_c ## name,                                                                   \
        qpel_mc11_c ## name,                                                                   \
        qpel_mc21_c ## name,                                                                   \
        qpel_mc31_c ## name,                                                                   \
        qpel_mc02_c ## name,                                                                   \
        qpel_mc12_c ## name,                                                                   \
        qpel_mc22_c ## name,                                                                   \
        qpel_mc32_c ## name,                                                                   \
        qpel_mc03_c ## name,                                                                   \
        qpel_mc13_c ## name,                                                                   \
        qpel_mc23_c ## name,                                                                   \
        qpel_mc33_c ## name,                                                                   \
    };
    
    QPEL_MC(0, _rnd)
    QPEL_MC(1, _no_rnd)
    
    
    int pix_abs16x16_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        int s, i;
    
        s = 0;
    
        for(i=0;i<16;i++) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            s += abs(pix1[0] - pix2[0]);
            s += abs(pix1[1] - pix2[1]);
            s += abs(pix1[2] - pix2[2]);
            s += abs(pix1[3] - pix2[3]);
            s += abs(pix1[4] - pix2[4]);
            s += abs(pix1[5] - pix2[5]);
            s += abs(pix1[6] - pix2[6]);
            s += abs(pix1[7] - pix2[7]);
            s += abs(pix1[8] - pix2[8]);
            s += abs(pix1[9] - pix2[9]);
            s += abs(pix1[10] - pix2[10]);
            s += abs(pix1[11] - pix2[11]);
            s += abs(pix1[12] - pix2[12]);
            s += abs(pix1[13] - pix2[13]);
            s += abs(pix1[14] - pix2[14]);
            s += abs(pix1[15] - pix2[15]);
            pix1 += line_size;
            pix2 += line_size;
        }
        return s;
    }
    
    
    int pix_abs16x16_x2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        int s, i;
    
        s = 0;
    
        for(i=0;i<16;i++) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
            s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
            s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
            s += abs(pix1[3] - avg2(pix2[3], pix2[4]));
            s += abs(pix1[4] - avg2(pix2[4], pix2[5]));
            s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
            s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
            s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
            s += abs(pix1[8] - avg2(pix2[8], pix2[9]));
            s += abs(pix1[9] - avg2(pix2[9], pix2[10]));
            s += abs(pix1[10] - avg2(pix2[10], pix2[11]));
            s += abs(pix1[11] - avg2(pix2[11], pix2[12]));
            s += abs(pix1[12] - avg2(pix2[12], pix2[13]));
            s += abs(pix1[13] - avg2(pix2[13], pix2[14]));
            s += abs(pix1[14] - avg2(pix2[14], pix2[15]));
            s += abs(pix1[15] - avg2(pix2[15], pix2[16]));
            pix1 += line_size;
            pix2 += line_size;
        }
        return s;
    }
    
    
    int pix_abs16x16_y2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        int s, i;
        UINT8 *pix3 = pix2 + line_size;
    
        s = 0;
    
        for(i=0;i<16;i++) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
            s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
            s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
            s += abs(pix1[3] - avg2(pix2[3], pix3[3]));
            s += abs(pix1[4] - avg2(pix2[4], pix3[4]));
            s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
            s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
            s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
            s += abs(pix1[8] - avg2(pix2[8], pix3[8]));
            s += abs(pix1[9] - avg2(pix2[9], pix3[9]));
            s += abs(pix1[10] - avg2(pix2[10], pix3[10]));
            s += abs(pix1[11] - avg2(pix2[11], pix3[11]));
            s += abs(pix1[12] - avg2(pix2[12], pix3[12]));
            s += abs(pix1[13] - avg2(pix2[13], pix3[13]));
            s += abs(pix1[14] - avg2(pix2[14], pix3[14]));
            s += abs(pix1[15] - avg2(pix2[15], pix3[15]));
            pix1 += line_size;
            pix2 += line_size;
            pix3 += line_size;
        }
        return s;
    }
    
    
    int pix_abs16x16_xy2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        int s, i;
        UINT8 *pix3 = pix2 + line_size;
    
        s = 0;
    
        for(i=0;i<16;i++) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
            s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
            s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
            s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
            s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
            s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
            s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
            s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
            s += abs(pix1[8] - avg4(pix2[8], pix2[9], pix3[8], pix3[9]));
            s += abs(pix1[9] - avg4(pix2[9], pix2[10], pix3[9], pix3[10]));
            s += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11]));
            s += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12]));
            s += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13]));
            s += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
            s += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
            s += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
            pix1 += line_size;
            pix2 += line_size;
            pix3 += line_size;
        }
        return s;
    }
    
    
    int pix_abs8x8_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    {
        int s, i;
    
        s = 0;
        for(i=0;i<8;i++) {
            s += abs(pix1[0] - pix2[0]);
            s += abs(pix1[1] - pix2[1]);
            s += abs(pix1[2] - pix2[2]);
            s += abs(pix1[3] - pix2[3]);
            s += abs(pix1[4] - pix2[4]);
            s += abs(pix1[5] - pix2[5]);
            s += abs(pix1[6] - pix2[6]);
            s += abs(pix1[7] - pix2[7]);
            pix1 += line_size;
            pix2 += line_size;
        }
        return s;
    }
    
    int pix_abs8x8_x2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    {
        int s, i;
    
        s = 0;
        for(i=0;i<8;i++) {
            s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
            s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
            s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
            s += abs(pix1[3] - avg2(pix2[3], pix2[4]));
            s += abs(pix1[4] - avg2(pix2[4], pix2[5]));
            s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
            s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
            s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
            pix1 += line_size;
            pix2 += line_size;
        }
        return s;
    }
    
    int pix_abs8x8_y2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    {
        int s, i;
        UINT8 *pix3 = pix2 + line_size;
    
        s = 0;
        for(i=0;i<8;i++) {
            s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
            s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
            s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
            s += abs(pix1[3] - avg2(pix2[3], pix3[3]));
            s += abs(pix1[4] - avg2(pix2[4], pix3[4]));
            s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
            s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
            s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
            pix1 += line_size;
            pix2 += line_size;
            pix3 += line_size;
        }
        return s;
    }
    
    int pix_abs8x8_xy2_c(UINT8 *pix1, UINT8 *pix2, int line_size)
    {
        int s, i;
        UINT8 *pix3 = pix2 + line_size;
    
        s = 0;
        for(i=0;i<8;i++) {
            s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
            s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
            s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
            s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
            s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
            s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
            s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
            s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
            pix1 += line_size;
            pix2 += line_size;
            pix3 += line_size;
        }
        return s;
    }
    
    
    /* permute block according so that it corresponds to the MMX idct
       order */
    
     /* general permutation, but perhaps slightly slower */
    
    void block_permute(INT16 *block)
    {
    	int i;
    	INT16 temp[64];
    
    	for(i=0; i<64; i++) temp[ block_permute_op(i) ] = block[i];
    
    	for(i=0; i<64; i++) block[i] = temp[i];
    }
    #else
    
    
    void block_permute(INT16 *block)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int i;
    
    
        for(i=0;i<8;i++) {
            tmp1 = block[1];
            tmp2 = block[2];
            tmp3 = block[3];
            tmp4 = block[4];
            tmp5 = block[5];
            tmp6 = block[6];
            block[1] = tmp2;
            block[2] = tmp4;
            block[3] = tmp6;
            block[4] = tmp1;
            block[5] = tmp3;
            block[6] = tmp5;
            block += 8;
        }
    }
    
    void clear_blocks_c(DCTELEM *blocks)
    {
        memset(blocks, 0, sizeof(DCTELEM)*6*64);
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    /* XXX: those functions should be suppressed ASAP when all IDCTs are
       converted */
    void gen_idct_put(UINT8 *dest, int line_size, DCTELEM *block)
    {
        ff_idct (block);
        put_pixels_clamped(block, dest, line_size);
    }
    
    void gen_idct_add(UINT8 *dest, int line_size, DCTELEM *block)
    {
        ff_idct (block);
        add_pixels_clamped(block, dest, line_size);
    }
    
    
    void dsputil_init(void)
    {
        int i, j;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int use_permuted_idct;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
        for(i=0;i<MAX_NEG_CROP;i++) {
            cropTbl[i] = 0;
            cropTbl[i + MAX_NEG_CROP + 256] = 255;
        }
    
        for(i=0;i<512;i++) {
            squareTbl[i] = (i - 256) * (i - 256);
        }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        ff_idct = NULL;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        get_pixels = get_pixels_c;
    
        diff_pixels = diff_pixels_c;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        put_pixels_clamped = put_pixels_clamped_c;
        add_pixels_clamped = add_pixels_clamped_c;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        gmc1= gmc1_c;
    
        clear_blocks= clear_blocks_c;
    
        pix_sum= pix_sum_c;
        pix_norm1= pix_norm1_c;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        pix_abs16x16     = pix_abs16x16_c;
        pix_abs16x16_x2  = pix_abs16x16_x2_c;
        pix_abs16x16_y2  = pix_abs16x16_y2_c;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        pix_abs16x16_xy2 = pix_abs16x16_xy2_c;
    
        pix_abs8x8     = pix_abs8x8_c;
        pix_abs8x8_x2  = pix_abs8x8_x2_c;
        pix_abs8x8_y2  = pix_abs8x8_y2_c;
        pix_abs8x8_xy2 = pix_abs8x8_xy2_c;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        use_permuted_idct = 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        dsputil_init_mmx();
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #ifdef ARCH_ARMV4L
        dsputil_init_armv4l();
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #ifdef HAVE_MLIB
        dsputil_init_mlib();
        use_permuted_idct = 0;
    #endif
    
    #ifdef ARCH_ALPHA
        dsputil_init_alpha();
        use_permuted_idct = 0;
    #endif
    
    #ifdef ARCH_POWERPC
        dsputil_init_altivec();
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (ff_idct == NULL) {
            ff_idct_put = simple_idct_put;
            ff_idct_add = simple_idct_add;
            use_permuted_idct=0;
    
        }
    #endif
        if(ff_idct != NULL) {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            ff_idct_put = gen_idct_put;
            ff_idct_add = gen_idct_add;
        }
    
        if(use_permuted_idct)
    #ifdef SIMPLE_IDCT
            for(i=0; i<64; i++) permutation[i]= simple_mmx_permutation[i];
    #else
            for(i=0; i<64; i++) permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
    #endif
        else
            for(i=0; i<64; i++) permutation[i]=i;
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        for(i=0; i<64; i++) inv_zigzag_direct16[zigzag_direct[i]]= i+1;
        for(i=0; i<64; i++) zigzag_direct_noperm[i]= zigzag_direct[i];
        
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (use_permuted_idct) {
            /* permute for IDCT */
            for(i=0;i<64;i++) {
                j = zigzag_direct[i];
                zigzag_direct[i] = block_permute_op(j);
                j = ff_alternate_horizontal_scan[i];
                ff_alternate_horizontal_scan[i] = block_permute_op(j);
                j = ff_alternate_vertical_scan[i];
                ff_alternate_vertical_scan[i] = block_permute_op(j);
            }
    
            block_permute(ff_mpeg1_default_intra_matrix);
            block_permute(ff_mpeg1_default_non_intra_matrix);
    
            block_permute(ff_mpeg4_default_intra_matrix);
            block_permute(ff_mpeg4_default_non_intra_matrix);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        
        build_zigzag_end();
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    }
    
    /* remove any non bit exact operation (testing purpose) */
    void avcodec_set_bit_exact(void)
    {
    #ifdef HAVE_MMX
        dsputil_set_bit_exact_mmx();
    #endif
    }
    
    
    void get_psnr(UINT8 *orig_image[3], UINT8 *coded_image[3],
                  int orig_linesize[3], int coded_linesize,
                  AVCodecContext *avctx)
    {
        int quad, diff, x, y;
        UINT8 *orig, *coded;
        UINT32 *sq = squareTbl + 256;
        
        quad = 0;
        diff = 0;
        
        /* Luminance */
        orig = orig_image[0];
        coded = coded_image[0];
        
        for (y=0;y<avctx->height;y++) {
            for (x=0;x<avctx->width;x++) {
                diff = *(orig + x) - *(coded + x);
                quad += sq[diff];
            }
            orig += orig_linesize[0];
            coded += coded_linesize;
        }
       
        avctx->psnr_y = (float) quad / (float) (avctx->width * avctx->height);
        
        if (avctx->psnr_y) {
            avctx->psnr_y = (float) (255 * 255) / avctx->psnr_y;
            avctx->psnr_y = 10 * (float) log10 (avctx->psnr_y); 
        } else
            avctx->psnr_y = 99.99;
    }